記一段《能力陷阱》的一段話:
我們很樂於去做那些我們擅長的事,於是就會一直去做,最終就使得我們會一直擅長那些事。做得越多,就越擅長,越擅長就越願意去做。這樣的一個循環能讓我們在這方面獲得更多的經驗,但卻容易陷入能力陷阱,在其他方面無法突破。
溫水煮青蛙—— 每個人都要特別警惕這種能力陷阱,避免把大量時間花在日常瑣事上。
與君共勉
關於二進制的問題主要涉及以下幾種操作:
- 與
- 或
- 非
- 異或
- 左右移動
693. 交替位二進制數 該題是在小米公司面試過程中被問到的,當時只想到用異或操作並給出了自己的思路。
這次我們一起來看一下這道題:
題意:給定一個正整數,檢查他是否爲交替位二進制數:換句話說,就是他的二進制數相鄰的兩個位數永不相等。
1.面試官想要的答案
1.1 發現規律
二進制交替不相等,無非就兩種情況:
…0101
…1010
先左右移動試一下:
n | 二進制 | n << 1 | n>>1 |
---|---|---|---|
5 | 101 | 1010 | 10 |
10 | 1010 | 10100 | 0101 |
這裏有個基礎知識:
- 正數左移等價於低位補0,相當於乘以2的操作;
- 正數右移等價於高位補0,相當於除以2的操作;
- 高位在左,低位在右,別搞錯了;
嘗試這將左右移後結果和原數做異或操作
異或的作用:
相同的數異或,結果爲0;
0與任意數異或,結果是自身;
n | 二進制 | n>>1 | n & n>>1) |
---|---|---|---|
5 | 101 | 10 | 111 |
8 | 1010 | 101 | 1111 |
10 | 10100 | 0101 | 11101 |
通過上面的表格:
我們可以發現:滿足條件的數,右移之後與自身異或後全是1。(PS:左移沒有這個規律,不信可以手動試一下)
1.2 利用規律
接下來我們的問題:
如何判斷一個數的二進制每一位都是1呢?
可以考慮,逆否命題 :能不能把每一位都變成0
這樣只需要判斷結果等於0即可。
動動手試一下吧!!!
n | 二進制 | n+1的二進制 |
---|---|---|
1 | 1 | 10 |
3 | 11 | 100 |
7 | 111 | 1000 |
15 | 1111 | 10000 |
到這裏對於有計算機基礎的人應該都明白啦,兼顧一下其它專業的朋友。(PS:計算機中存儲位數是相等的,無非就是補0)
n | 二進制 | n+1的二進制 |
---|---|---|
1 | 00000001 | 00000010 |
3 | 00000011 | 00000100 |
7 | 00000111 | 00001000 |
15 | 00001111 | 00010000 |
這兩者進行與操作可以將所有位全部變成0.這樣我們的目的就達到啦。
1.3 TIC(Talk is cheap)
這裏我們需要考慮整數溢出的情況:
public boolean hasAlternatingBits(int n) {
public boolean hasAlternatingBits(int n) {
long tmp = (n ^ (n>>1));
return (tmp & (tmp+1)) == 0;
}
2. 笨思妙想
二進制中只存在0和1,如果不是交替出現,則必然會出現00 或者 11。
2.1 利用二進制字符串
public boolean hasAlternatingBits2(int n) {
String binaryString = Integer.toBinaryString(n);
return binaryString.contains("00") || binaryString.contains("11");
}
2.2 遍歷法1
邏輯運算:與操作
public boolean hasAlternatingBits(int n) {
while(n>0)
{
int last =n&1; //最後一位
int next=(n>>1)&1; //第二位
if(last ==next) return false;
n=(n>>1);
}
return true;
}
2.2 遍歷法2
算術運算:取餘 & 除
將十進制轉化爲二進制
public boolean hasAlternatingBits(int n) {
while(n>0)
{
int last =n % 2; //最後一位
int next= n / 2 % 2; //倒數第二位
if(cur==next) return false;
n= n / 2 ;
}
return true;
}
2.3 總結
本質上2.1 和 2.2的實現原理是一樣的。
n % 2 == n % 1
n / 2 == n >> 1
3. XCD
對於像我這種沒有ACM等算法相關經歷的開發者,在面試的過程中,難免遇到自己解不出來的算法題。個人認爲能向面試官展示自己思路和分析邏輯,只要能答道點上,都還是有機會的。
不過刷算法肯定是百利而無一害的。
後續我會將算法的代碼專門整理到Github上面的。