LeetCode上的Bit Manipulation(位運算)型別的題目
文章目錄
- Easy
- 461. Hamming Distance兩個數字的漢明距
- 476. Number Complement 求補碼
- 136. Single Number
- 693. Binary Number with Alternating Bits 相互交錯的位資訊
- 389. Find the Difference
- 371. Sum of Two Integers 不使用加減號進行兩個整數的相加
- 169. Majority Element 出現次數大於一半的元素
- 268. Missing Number 找出0到n中缺失的那個數字
- 191. Number of 1 Bits 整數二進位制表達中有多少個1
- Medium
Easy
461. Hamming Distance兩個數字的漢明距
兩個整數之間的漢明距離是相應位不同的位置數。
正常思路是以下的程式碼:
判斷兩個數字位資訊最後一位是是否不一樣,再集體右移一位。
class Solution { public int hammingDistance(int x, int y) { int res = 0; while(x != 0 || y != 0){ if((x&1) != (y&1)) res++; x = x>>1; y = y>>1; } return res; } }
faster than 50.77% of Java online submissions for Hamming Distance.
但是位運算有技巧就是:
- 兩個整數相異或,得到的是兩個整數位資訊所有不同的資訊。因為異或^表示不同為1,相同為0.
- n &= (n-1) 可以抹掉n的位資訊中最右邊的1
所以這道題於是可以這麼寫:
class Solution { public int hammingDistance(int x, int y) { int xor = x ^ y, count = 0; while (xor != 0) { xor &= (xor - 1); count++; } return count; } }
faster than 60.28% of Java online submissions for Hamming Distance.
476. Number Complement 求補碼
num=101
mask=111…111000
~mask=000…000111
~num=111…111010
~num & ~mask = 010
class Solution {
public int findComplement(int num) {
int mask = ~0;
while((num&mask) > 0) mask <<= 1;
return ~num & ~mask;
}
}
faster than 99.01% of Java online submissions for Number Complement.
136. Single Number
給定一個非空的整數陣列,除了一個元素外,每個元素都會出現兩次,找到那一個。
需要知道 異或^ 的以下特點:
- 兩個相同的數異或的結果為0
- 0異或數字等於原數字
class Solution {
public int singleNumber(int[] nums) {
int res = 0;
for(int i : nums){
res ^= i;
}
return res;
}
}
faster than 100.00% of Java online submissions for Single Number.
693. Binary Number with Alternating Bits 相互交錯的位資訊
693. Binary Number with Alternating Bits
給定正整數,檢查它的位表示是否是交替位,即兩個相鄰位總是具有不同的值。
解釋:
n = 1 0 1 0 1 0 1 0
n >> 1 = 0 1 0 1 0 1 0 1
n ^ n>>1 = 1 1 1 1 1 1 1 1
n = 1 1 1 1 1 1 1 1
n + 1 = 1 0 0 0 0 0 0 0 0
n & (n+1) = 0 0 0 0 0 0 0 0
class Solution {
public boolean hasAlternatingBits(int n) {
n ^= n >> 1;
return (n&(n+1)) == 0;
}
}
faster than 9.41% of Java online submissions for Binary Number with Alternating Bits.
389. Find the Difference
給定兩個字串s和t,它們只包含小寫字母。 字串t由隨機混洗字串s生成,然後在隨機位置再新增一個字母。 找到t中新增的字母。
用一個256的陣列map來記錄位資訊,map[i]=a表示字元的ASCII碼為i的字元在字串中出現了a次。
class Solution {
public char findTheDifference(String s, String t) {
int[] pos = new int[256];
for(int i = 0; i < s.length(); i++){
pos[s.charAt(i)]++;
}
for(int i = 0; i < t.length(); i++){
if(pos[t.charAt(i)] == 0){
return t.charAt(i);
}
pos[t.charAt(i)]--;
}
return ' ';
}
}
faster than 67.92% of Java online submissions for Find the Difference.
371. Sum of Two Integers 不使用加減號進行兩個整數的相加
不使用加減號實現兩個整數的相加
- a^b等於a和b的無進位相加
- a&b再左移以為相當於a+b的進位
- 一直重複直到進位消失
class Solution {
public int getSum(int a, int b) {
int sum = a;
while (b != 0) {
sum = a ^ b;
b = (a & b)<<1;
a = sum;
}
return a;
}
}
faster than 100.00% of Java online submissions for Sum of Two Integers.
169. Majority Element 出現次數大於一半的元素
給定大小為n的陣列,找到多數元素。多數元素是出現超過⌊n /2⌋倍的元素。 您可以假設該陣列非空,並且多數元素始終存在於陣列中。
這道題出現在Bit Manipulation的分類下面,說明可以用位運算去解,但是有更容易理解的方法:
出現次數大於一半的數只會有一個,一次在陣列刪掉兩個不同的數,不停滴刪除,直到剩下的數只有一種(不是一個),這個數就是答案。
class Solution {
public int majorityElement(int[] nums) {
int num = 0;
int count = 0;
for(int i : nums){
if(count == 0){
num = i;
count++;
}else if(num == i){
count++;
}else{
count--;
}
}
return num;
}
}
faster than 93.88% of Java online submissions for Majority Element.
268. Missing Number 找出0到n中缺失的那個數字
給定一個包含n個不同數字的陣列,由0,1,2,…,n組成,找到陣列中缺少的數字。
利用異或的特點:
- 兩個相同的數異或的結果為0
- 0異或數字等於原數字
class Solution {
public int missingNumber(int[] nums) {
int missing = 0;
for(int i = 1; i <= nums.length; i++){
missing ^= i;
}
for(int i = 0; i < nums.length; i++){
missing ^= nums[i];
}
return missing;
}
}
faster than 69.45% of Java online submissions for Missing Number.
191. Number of 1 Bits 整數二進位制表達中有多少個1
整數二進位制表達中有多少個1?
利用位運算以下特點:
- n &= n-1 抹掉最右邊的1
public class Solution {
// you need to treat n as an unsigned value
public int hammingWeight(int n) {
int count = 0;
while(n != 0){
n &= n-1;
count++;
}
return count;
}
}
faster than 98.49% of Java online submissions for Number of 1 Bits.
Medium
260. Single Number III
給定一組數字nums,其中恰好兩個元素只出現一次而所有其他元素恰好出現兩次。找到只出現一次的兩個元素。
假設這兩個數是a和b,用異或的特點,數組裡面的數全部異或一遍,剩下的結果肯定是a^b。
於是用a^b的結果再在陣列中把a和b給區分出來。在 a^b 上找到一個不為0的bit位,那麼在a和b上肯定有一個這個位上位0,另外一個為1.我們用最左邊的一個1作為這個bit位。
再記住一個特點:
- n&(~n+1) 留下n的二進位制表示的最右邊的一個1
class Solution {
public int[] singleNumber(int[] nums) {
int tag = 0;
for(int i : nums){
tag ^= i;
}
int[] res = new int[2];
tag = tag&(~tag+1);
for(int i : nums){
if((i&tag) == 0){
res[0] ^= i;
}else{
res[1] ^= i;
}
}
return res;
}
}
faster than 100.00% of Java online submissions for Single Number III.