- 涉及單雙數問題時,可以考慮使用異或(136)
- 位操作求加減:
int getSum(int a, int b) {
while (b!=0) {
int num = a^b;//按位y異或
b = (unsigned int)(a&b)<<1;//按位進位
a = num;
}
return a;
}
-
判斷循環鏈表的方法:walker-runner法。
就是說通過一個慢指針和一個快指針同時出發,如果兩者在某一時刻相遇,且均不爲NULL,則該鏈表是循環的。
此時將快指針再次從頭結點出發,速度和慢節點持平,再次和慢指針相遇時就是環的入口。 -
從低到高不方便操作時,換個思考方式,從高到低排。
-
n = (n-1)&n 結果是讓n最右邊的1變成0
-
實現數值的整數次方。需要考慮的因素:底數爲0,指數爲0或負數。
數值的整數次方 -
調整數組使奇數位於前偶數位於後。
雙指針,重點是可擴展的版本 奇偶對調 -
倒數第K個節點
雙指針,考慮代碼的robust。輸入頭結點是否爲空?循環中途是否會指向空(即,K比整個鏈表的長度還長)?輸入K是否合法(K==0)? -
剪繩子問題中,需要注意,繩子小端長度爲3時,最優,其次長度爲2,最後長度爲1。剪繩子
-
數組中的衆數
摩爾投票,總是認爲當前數爲衆數,遇到和當前不同的數就票數-1。因爲衆數是超過數組一般以上的數,因此最後留下來的總是正確的結果。 -
數字序列中某一位的數字
這類題的共性:劃分開不同位數去處理,1-9有9個數,10-99有90個數,100-999有900個數…
數字序列中某一位的數字 -
1~n整數中1出現的次數
把問題切分爲小問題解決。累加個位,十位,百位…每位上出現1的數量。詳細見代碼。
舉例:
對於102分別有三種情況:- 個位數是2,大於1:統計從[00-10]所有個位上有1的情況,共11種。
- 十位數是0,小於1:統計從[0]上所有十位是1的情況,有10種。
- 百位數是1,等於1: 統計百位爲1的情況,取決於後面的值,爲2+1種。
共計24種。
1~n整數中1出現的次數 -
醜數
動態規劃,第n個醜數一定存在於乘上2,3,5後比target前一個醜數要大的數中,動態規劃可解決。
醜數 -
數組中的逆序對
用到了歸併排序的思想。通過判斷左子序列能夠一次性判斷許多情況。 -
圓圈中最後剩下的數字
我們將上述問題建模爲函數 f(n, m),該函數的返回值爲最終留下的元素的序號。首先,長度爲 n 的序列會先刪除第 m % n 個元素,然後剩下一個長度爲 n - 1 的序列。那麼,我們可以遞歸地求解 f(n - 1, m),就可以知道對於剩下的 n - 1 個元素,最終會留下第幾個元素,我們設答案爲 x = f(n - 1, m)。
由於我們刪除了第 m % n 個元素,將序列的長度變爲 n - 1。當我們知道了 f(n - 1, m) 對應的答案 x 之後,我們也就可以知道,長度爲 n 的序列最後一個刪除的元素,應當是從 m % n 開始數的第 x 個元素。因此有 f(n, m) = (m % n + x) % n = (m + x) % n。