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
        • 260. Single Number III


Easy

461. Hamming Distance两个数字的汉明距

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 求补码

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

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

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 不使用加减号进行两个整数的相加

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 出现次数大于一半的元素

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中缺失的那个数字

268. Missing Number

给定一个包含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

191. Number of 1 Bits

整数二进制表达中有多少个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

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.

你可能感兴趣的:(LeetCode题的自我理解)