338 counting bits。輸入乙個整數n,對於 0 ≤ i ≤ num,計算每個數的二進位制1的個數。例如:num = 5 返回 [0,1,1,2,1,2]。希望能在o(n)的時間內完成。這裡有動態規劃的思想。
思路一:
十進位制數
二進位制表示
000001
0011+(0的bits)
201013
0111+(1的bits)
410015
1011+(1的bits)
6110
1+(2的bits)
7111
1+(3的bits)
8100019
10001
1+(1的bits)
1010010
1+(2的bits)
1110011
1+(3的bits)…
觀察可以發現,值為2n
的時候,1的位數為1。其他情況下數,就是1+【從0開始的數1的位數】。
public
int countbits3(int num)
return r;
}
思路二:發現乙個規律:,7=111 ,由011->111新增了1個1;6=110,由011->110,1的個數不變,但是1的位置變了。從0daonum是乙個不斷變換1的位置或者不斷加1的過程,這樣就將任意乙個數i,與i/2聯絡起來了。
public
int countbits(int num)
return r;
}
i&1,當數字為偶數就加0,如果是奇數就加1。
318 maximum product of word lengths。最大的單詞長度乘積。輸入乙個字串陣列words,返回最大的length(words[i])*length(words[j]),i≠
j ,並且單詞i和單詞j不含有公共字元。
思路一:難點是判斷兩個字串是否包含相同字母。可以乙個個遍歷找到,效率會比較低。看看用位運算能怎麼做。一共26個小寫字母。表示不同的字母可以用one-hot型別表示(從詞向量表示方法得到的啟示)。
z = 10000…000(一共25個0)
y = 01000…000(一共25個0)
… a = 0000…001
用26位的二進位制表示不同的字母。
這樣乙個字串 abc = 000….111
azc = 100…..101
兩個字串的值做與操作。如果結果為0,則說明沒有相同字元。
public int maxproduct(string words)
}int maxproduct = 0;
for (int i = 0; i < n - 1; i++) }}
}return maxproduct;
}
137 single number ii。給定乙個陣列,每個數字出現三次,只有乙個數字出現了一次。找到這個數字。
思路一:以前有個題目是說每個字母出現兩次,只有乙個字母出現了一次。這樣用異或操作,就能找到只出現了一次的字母。但是出現三次?這裡方法不管用了。
計算陣列中所有數字的每一bit1的個數。1=01,如果陣列中有三個1,那麼第0位的1就有3個,3%3=0。你肯定會問題如果陣列中有三個1和3呢?那第0位的1就會有6個,6%3=0。但是如果只有2個3,那第0位的1就只有5個,5%3!=0。那3就是要找的數字了。
public
int singlenumber(int nums)
result += ((sum % 3)}
260 single number iii。輸入陣列nums,每個數字都恰好出現了兩次。但是有兩個數字,都只出現了一次。找到這兩個數字。
思路:記錄只出現了1次的兩個數分別為a,b。
出現了2次的時候,找不同,肯定需要異或操作。對所有nums的元素做異或,最後得到的是r=a|b。如果r的第i位等於1,那說明a和b在這個位置是有分歧的。我們利用這乙個bit就可以將nums陣列分為第i位是0和第i位是1,兩個部分。這個時候再做異或,就能去掉出現了兩次的數,留下只有一次的數。
只留下乙個數某一位為1,其他都為0,的操作是:n &=-n。
public
int singlenumber(int nums)
diff &= -diff;
for (int num : nums) else
}return ans;
}
78 subsets
思路:求子集,就是將陣列中每乙個元素,或者取或者不取,組合起來。從二進位制的角度來表示。例如nums=[1,2,3]。下標分別是 0,1,2。每次取乙個,2個,三個就遍歷完成了。
用1表示取這一位的數字。
下標: 0 1 2
組合 0 0 0 =0
1 0 0 =4
0 1 0 =2
0 0 1 =1
1 1 0 =6
1 0 1 =5
0 1 1 =3
1 1 1 =7
發現下標用0 1 表示後的值就是從0到7. 7=2^3-1。所以找到規律。
做了這麼久,第一次直接找到最佳回答。
顯然還可以用深度優先搜尋的思路理解。
public
list
> subsets(int nums)
}result.add(list);
}return result;
}
總結:這次關於二進位制習題的覆盤就結束了。整個做題的過程還是比較沮喪的。平時二進位制操作用的比較少。前面的習題基本都是得看答案才能知道二進位制該怎麼用。這些操作在筆記中,用加粗符號標記出來了。當習題做到中間的時候,已經開始能想到用什麼操作,能實現什麼功能了。但是還不能完全做對。到了最後終於能找到感覺了。這也說明了練習,總結,才能掌握一門技巧。多次練習、總結終會學到一門技巧。解決問題過程中,對規律的觀察和總結,是解題的關鍵。 二進位制 二進位制起源
現代通訊技術的基礎是二進位制編碼。早在1865年麥克斯韋總結出麥克斯韋方程組之前,美國人摩斯 morse 於1837年發明了摩斯電碼和有線電報。有線電報的出現,具有劃時代的意義 它讓人類獲得了一種全新的資訊傳遞方式,這種方式 看不見 摸不著 聽不到 完全不同於以往的信件 旗語 號角 烽火,這也是二進...
判斷二進位製半整數(二進位制)
10年後,tokitsukaze大佬已經變成了年收入超百萬的的精英程式設計師,家裡沒錢也沒礦的teitoku,找tokitsukaze大佬借1000塊錢,然後tokitsukaze大佬說,借你1024吧,湊個整數。沒錯在2進製下1024是 二進位制整數 乙個正整數滿足其值為2的k次方 k為正整數 我...
mysql二進位制 MySql二進位制連線方式詳解
使用mysql二進位制方式連線 您可以使用mysql二進位制方式進入到mysql命令提示符下來連線mysql資料庫。例項以下是從命令列中連線mysql伺服器的簡單例項 root host mysql u root p enter password 在登入成功後會出現 mysql 命令提示視窗,你可以...