生活随笔
收集整理的這篇文章主要介紹了
LeetCode——数学
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
LeetCode——數學
目錄
最大公約數最小公倍數 1. 生成素數列表 2. 最大公約數
進制轉換
7進制 16進制 26進制 階乘
統計階乘尾部有多少個0 字符串加減法
二進制加法 字符串加法 相遇問題
改變數組元素使所有的數組元素都相等 其他
平方數 3的n次方 乘積數組
1. 最大公約數最小公倍數
1. 生成素數序列
素數分解 1. 每一個數都可以分解成素數的乘積
思路 1. 創建一個n+1大小的boolean數組和值為0的count變量 2. 因為素數是從2開始的,所以直接從2開始遍歷,如果數組為true,說明不是素數,否則count++ 3. 然后創建變量j,j=i*i,依次加i遍歷,得到不是素數的數,將此位置上的數組設置為true
代碼
public static
int countPrimes
( int n
) {
boolean [ ] notPrimes
= new
boolean [ n
+ 1 ] ; int count
= 0 ; for ( int i
= 2 ; i
< n
; i
+ + ) {
if ( notPrimes
[ i
] ) {
continue ; }count
+ + ; for ( long j
= ( long
) i
* i
; j
< n
; j
+ = i
) {notPrimes
[ ( int ) j
] = true ; }}
return count
; }
2. 最大公約數
1. 最大公約數
利用輾轉相除法
2. 最大公倍數
最小公倍數為兩數的乘積除以最大公約數 代碼
public static
int gcd
( int a
, int b
) {
return b
= = 0 ? a : gcd
( b
, a
% b
) ; }
public static
int lcm
( int a
, int b
) {
return a
* b
/ gcd
( a
, b
) ; }
3. 進制轉換
1. 7進制
思路 1. 如果需要轉換的數為0,直接返回字符串0 2. 不為0則創建StringBuilder用于字符串的拼接,判斷num是否為負,如果為負則轉換為正數,最后結果添加“-”即可 3. 當num大于0,sb追加num%7的數,然后num=num/7 4. 得出結果要反轉字符串,最后判斷原始的數如果為負數,則添加“-”號,否則直接輸出結果 代碼
public static String convertToBase7
( int num
) {
if ( num
= = 0 ) {
return "0" ; }StringBuffer sb
= new StringBuffer
( ) ; boolean isNegative
= num
> 0 ; if ( ! isNegative
) {num
= - num
; }
while ( num
> 0 ) {sb
. append
( num
% 7 ) ; num
/ = 7 ; }String res
= sb
. reverse
( ) . toString
( ) ; return isNegative?res:
"-" + res
; }
補充 1. java中static String toString(int num, int radix)可以將一個整數轉換為radix進制表示的字符串
public String convertToBase7
( int num
) {
return Integer . toString
( num
, 7 ) ;
}
2. 16進制
思路 創建char數組存儲1~f,創建StringBuilder用于拼接字符串 當num不為0時,num&0b1111(0b表示是二進制)得到的值在map中查找對應的值,然后num無符號右移4位 因為負數就要用它的補碼形式,因此符號位不能有特殊的意義,需要使用無符號位右移,左邊填0 1. <<表示左移,不分正負數,低位補0 2. >>表示右移,如果該數為正,則高位補0,若為負數,則高位補1 3. >>>表示無符號右移,也叫邏輯右移,即若該數為正,則高位補0,若該數為負數,則右移后高位同樣補0 代碼
public static String toHex
( int num
) {
if ( num
= = 0 ) {
return "0" ; }
char [ ] map
= {
'0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' , 'a' , 'b' , 'c' , 'd' , 'e' , 'f' }
; StringBuffer sb
= new StringBuffer
( ) ; while ( num
!= 0 ) {sb
. append
( map
[ num
& 0 b1111
] ) ; num
>> >= 4 ; }
return sb
. reverse
( ) . toString
( ) ; }
3. 26進制
思路 1. 因為是從1開始計算的,而不是從0開始的,因此需要對n執行-1,操作 代碼
public static String convertToTitle
( int n
) {
if ( n
= = 0 ) {
return "" ; }n
return convertToTitle
( n
/ 26 ) + ( char ) ( n
% 26 + 'A' ) ; }
4. 階乘
1. 統計階乘尾部有多少個0
思路 尾部的0由2*5得來,2的數量明顯多于5的數量,因此只要統計有多少個5即可 代碼
public static
int trailingZeros
( int n
) {
return n
= = 0 ?
0 :n
/ 5 + trailingZeros
( n
/ 5 ) ; }
5. 字符串加減法
1. 二進制加法
概述
思路
取得字符串a,b的最后一個字節下標,創建變量carry用來記錄是否需要進位,創建StringBuilder記錄結果 while循環從后往前遍歷字符串a,b 1. 如果i>=0并且字符串a最后一位是1,carry++ 2. 如果j>=0并且字符串b最后一位是1,carry++ str追加結果 1. 如果carry%2=0,說明需要進位,否則不需要 2. carry /=2 1. carry=2時,結果為1,說明需要進位 2. carry=1時,結果為0,說明不需要進位 代碼
public static String addBinary
( String a
, String b
) {
int i
= a
. length
( ) - 1 ; int j
= b
. length
( ) - 1 ; int carry
= 0 ; StringBuilder str
= new StringBuilder
( ) ; while ( carry
= = 1 || i
>= 0 || j
>= 0 ) {
if ( i
>= 0 && a
. charAt
( icarry
+ + ; }
if ( j
>= 0 && b
. charAt
( jcarry
+ + ; }str
. append
( carry
% 2 ) ; carry
/ = 2 ; }
return str
. reverse
( ) . toString
( ) ; }
2. 字符串加法
思路 1. 跟上題一樣,carry記錄進位的數,字符串a,b從后往前遍歷 代碼
public static String addStrings
( String num1
, String num2
) {StringBuilder str
= new StringBuilder
( ) ; int carry
= 0 ; int i
= num1
. length
( ) - 1 ; int j
= num1
. length
( ) - 1 ; while ( carry
= = 1 || i
>= 0 || j
>= 0 ) {
int x
= i
< 0 ?
0 : num1
. charAt
( i
int y
= j
< 0 ?
0 : num2
. charAt
( jstr
. append
( ( x
+ y
+ carry
) % 10 ) ; carry
= ( x
+ y
+ carry
) / 10 ; }
return str
. reverse
( ) . toString
( ) ; }
5. 相遇問題
1. 改變數組元素使所有的數組元素都相同
概述 1. 每次可以對一個數組元素加一或者減一,求最小改變的次數 思路 1. 典型是相遇問題,移動距離最小的方式是所有元素都移動到中位數。 1. 設m為中位數。a和b是m兩邊的兩個元素,且b>a。要使a和b相等,它們總移動次數為b-a,這個值等于(b-m)+(m-a),也就是把這兩個數移動到中位數的移動次數 2. 具體就是先將數組nums排序,創建遍歷move記錄移動次數,l,h記錄開始和結尾下標 3. while循環,當l<=h時,move記錄nums[h]-nums[l],然后l++,h–,最后返回move即可 代碼
public static
int minMoves
( int [ ] nums
) {Arrays
. sort
( nums
) ; int move
= 0 ; int l
= 0 ; int h
= nums
. length
- 1 ; while ( l
<= h
) {move
+ = nums
[ h
] - nums
[ l
] ; l
+ + ; h}
return move
; }
6. 多數投票問題
1. 數組中出現次數多于n/2的元素
思路1 1. 先對數組排序,最中間那個數出現次數一定多于n/2 思路2 可以利用Boyer-Moore 投票算法,使得時間復雜度為O(N)。 1. 使用cnt來統計一個元素出現的次數,當遍歷到的元素和統計元素不相同時,令cnt–。如果前面查找了i個元素,且cnt==0,說明前i個元素沒有majority,或者右majority,但是出現次數少于i/2,因為如果多有i/2的話cnt就一定不為0.此時剩下的n-i個元素中,majority的數目依然多于(n-i)/2,因此繼續查找就能找出majority 代碼
public static
int majorityElement
( int [ ] nums
) {Arrays
. sort
( nums
) ; return nums
[ nums
. length
/ 2 ] ; }
public static
int majorityElement2
( int [ ] nums
) {
int cnt
= 0 ; int major
= nums
[ 0 ] ; for ( int num : nums
) {major
= ( cnt
= = 0 ) ? num : major
; cnt
= ( major
= = num
) ? cnt
+ 1 : cnt
- 1 ; }
return major
; }
7. 其他
1. 平方數
概述
思路 1. 平方序列:1,4,9,16… 2. 間隔:3,5,7… 3. 間隔為等差數列,使用這個特性可以從得到從1開始的平方序列
代碼
public static
boolean isPerfectSquare
( int num
) {
int isPer
= 1 ; while ( num
> 0 ) {num
- = isPer
; isPer
+ = 2 ; }
return num
= = 0 ; }
2. 3的n次方
思路 1162261467是32位系統中,3的最高次冪19 代碼
public static
boolean isPowerOfThree
( int n
) {
return n
> 0 && ( Math
. pow
( 3 , 19 ) % n
= = 0 ) ; }
3. 乘積數組
概述 1. 給定一個數組,創建一個新數組,新數組的每個元素為原始數組中除了該位置上的元素之外所有元素的乘積 2. 要求時間復雜度為O(N),并且不能使用除法 思路 1. 創建一個新數組products,先將數組元素填充為1。 2. 從前往后遍歷(從1開始),記錄當前下標i左邊的乘積left,將left乘于products[i],則記錄了該下標的左邊元素 3. 同理,從后往前遍歷(從n-2開始),記錄當前下標i的右邊元素乘積right,將right乘于products[i],則記錄了該下標的右邊元素 代碼
public static
int [ ] productExceptSelf
( int [ ] nums
) {
int n
= nums
. length
; int [ ] products
= new
int [ n
] ; Arrays
. fill
( products
, 1 ) ; int left = 1 ; for ( int i
= 1 ; i
< n
; i
+ + ) {
left * = nums
[ i
- 1 ] ; products
[ i
] * = left ; }
int right = 1 ; for ( int i
= n
- 2 ; i
>= 0 ; i
right * = nums
[ i
+ 1 ] ; products
[ i
] * = right ; }
return products
; }
總結
以上是生活随笔 為你收集整理的LeetCode——数学 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。