面試中常見的位運算題目

2021-09-19 19:02:38 字數 4431 閱讀 7298

a = 11111111111111111111111110000001

b = 2

a >> b = 11111111111111111111111111100000

a >>> b = 00111111111111111111111111100000

題目:給出乙個整數n,求其二進位制表示中1的個數。

思路: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...