a = 11111111111111111111111110000001題目:給出乙個整數n,求其二進位制表示中1的個數。b = 2
a >> b = 11111111111111111111111111100000
a >>> b = 00111111111111111111111111100000
思路:1.每次根據技巧一去掉一位1,進行統計;2.定義乙個mask與原數的每一位進行與運算
// 求乙個數中1的個數
public
static
intnumberofone1
(int n)
return cnt;
}//求乙個數中1的個數
public
static
intnumberofone2
(int n)
mask <<=1;
}return cnt;
}
題目:判斷乙個數是否為2的冪或者為4的冪
思路:1.如果為2的冪則二進位制表示中1僅可出現一次;2.如果為4的冪,首先是2的冪,然後需要保證二進位制中1的位置在偶數字上;
//判斷乙個數是否是2的冪
public
static
boolean
ispowoftwo
(int n)
//判斷乙個數是否是4的冪
public
static
boolean
ispowoffour
(int n)
問題:在不借助輔助變數的前提下進行兩個變數之間的交換
思路:1.採用異或運算進行;2.採用 加減法運算進行
//位運算實現兩數交換,在不使用中間變數前提下
public
static
void
change
(int a ,
int b)
問題:乙個整數陣列中,僅有乙個(兩個)數出現一次,其他數都出現2次,找出這個數(這兩個數)
思路:1.使用異或運算技巧二,分別對所有數異或,最後的數即為所要找的數;
2. 首先利用異或運算得到兩個出現一次數的異或結果,然後根據其中某位的1將陣列分為兩部分(如果異或後的結果某位為1則表示所要找的兩個數在該位是不同的,這個劃分的依據),然後分別對兩個陣列求出現一次的數。
// 尋找乙個陣列中僅出現一次的數,這個數只有乙個
public
static
int(
int[
] nums,
int len)
return result;
}// 尋找乙個陣列中僅出現一次的數,這個數有兩個
public
static
int(
int[
] nums,
int len)
// 得到最後一位的1,並基於此將陣列分為兩部分
int bits = tmp &
(- tmp)
; list
arrays1 =
newarraylist
<
>()
; list
arrays2 =
newarraylist
<
>()
;for
(int i =
0; i < len; i++
)else
}// 分別在兩個陣列中尋找出現一次的數
// 此處可以直接呼叫出現一次的函式
tmp = arrays1.
get(0)
;for
(int i =
1; i < arrays1.
size()
; i++
) result[0]
= tmp;
tmp = arrays2.
get(0)
;for
(int i =
1; i < arrays2.
size()
; i++
) result[1]
= tmp;
return result;
}
問題:使用位運算實現加法和減法
思路:1.對於加法可以手動模擬運算,先進行無進製的加法,然後計算進製,然後迴圈計算無進製加法結果和進製結果,直到進製為0為止;
2.減法運算,相當於加上乙個負數,所以要先求減數的補碼,然後呼叫加法運算;
// 使用運運算實現加法
public
static
intaddbybit
(int x,
int y)
// // 進行不進製加法
// int sum = x ^ y;
// // 求進製
// int carry = (x & y) << 1;
// // 進製與不進製結果相加
// return addbybit(sum, carry);
// 迭代實現
int sum = x ^ y;
int carry =
(x & y)
<<1;
while
(carry !=0)
return sum;
}// x:減數;y:被減數
public
static
intsubstractbybit
(int x,
int y)
問題:給定兩個整數,求需要改變多少位使得兩個數相同
思路:利用異或運算,只需要改變不同位即可,相當於進行異或運算後求其1的個數
// 給定兩個整數,求改變多少位可以使得兩個數相同
public
static
intchangecount
(int n,
int m)
return cnt;
}
問題:輸入整數n, 計算0,n中所有數的二進位制表示中1的個數,返回乙個記錄個數的陣列
思路:1. 一遍遍歷,針對每個數都計算其二進位制1的個數;
2. 優化版本,乙個數的二進位制1個數等於去掉乙個數最後一位1所對應的數的個數加1。即:
count[i] = count[i & (i-1)] + 1;
// 計算0,n上各個數的二進位制表示中1的個數
public
static
int[
]findarraynumberofone
(int n)
// 優化方式
int[
] result =
newint
[n+1];
// 初始化第乙個數
result[0]
=0;for
(int i =
1; i <= n; i++
)return result;
}
問題:n皇后問題
思路:採用位運算
/**
* * @param row: 當前所在的行數
* @param col:所有的列
* @param pie: 左下角位置
* @param na: 右下角位置,即不允許皇后在一條斜率為1或者-1的斜線上
*/public
static
void
nqueen1
(int row,
int col ,
int pie,
int na)
// 選取一行中可以防止皇后的位置
int bits =(~
(col|pie|na))&
((1<< nqueen)-1
);while
(bits >0)
}
判斷乙個數是否在乙個集合中
對於乙個數僅需要儲存其是否存在,只需要兩個狀態,所以乙個位就能滿足條件,這樣乙個int型別的數可以表示32個數的狀態,可以把集合中的數通過位運算表示其狀態,然後判斷乙個數是否存在其中。裡面涉及到一些簡單的移位操作,可以自行搜尋。
布隆過濾器
判斷乙個數是否在乙個集合中。原理是對於乙個數通過若干個雜湊函式得到若干個雜湊值,將這些雜湊值表示在位圖中。如果乙個數在該集合中,那麼其所有雜湊值的二進位制位都應該是1;如果乙個數不在該集合中,原則上其所有雜湊值得二進位制位不全為1,但是會有誤差,因為可能是別的數字存在的緣故導致原本為0的位變為了1,這與點陣圖的大小、雜湊函式和雜湊函式的個數有關係。感興趣可以自行搜尋。
位運算題目
今天看到牛客網的一些題目,非常經典。解法基本也都很熟悉,所以特地做個總結,後續慢慢補充。先上題目 數字中的二進位制有多少個1 這裡的數字並不關心它的符號,所以即便是負數,只需要得到二進位制中1的個數就可以了。但是在python中,對於負數的右移運算,符號位會保留,這樣在執行迴圈語句的右移操作時,首位...
位運算題目彙總
給你乙個整數陣列 arr 請你將陣列中的元素按照其二進位制表示中數字 1 的數目公升序排序。如果存在多個數字二進位制中 1 的數目相同,則必須將它們按照數值大小公升序排列。請你返回排序後的陣列。輸入 arr 0 1,2 3,4 5,6 7,8 輸出 0,1,2,4,8,3,5,6,7 解釋 0 是唯...
有關面試中常見位運算總結
int numberof 1 int n return count int is 2n int n 1 求這兩個數的異或 兩個數不同的位置都為1,這些位置都需要改變 2 統計異或結果中1的個數 int stepchangeto int m,int n int add int num1,int num...