Bitwise AND of Numbers Range
实现范围内的按位与
思路:首先将m与n做按位与得到tmp。对于tmp中为0的位,则最终结果也一定为0;对于tmp中为1的位,则要看m到n中间有没有数的这一位为0,方法是:将m的这一位及其低位全部置1得到数a,如果a<n,则说明m到n中间存在这一位为0的数。
1 public class Solution { 2 public int rangeBitwiseAnd(int m, int n) { 3 int res = m & n; 4 5 for (int j = 0; j < 31; j++) { 6 if ((res & (1 << j)) != 0) { //如果第j位为0 7 int a = 1 << (j + 1); 8 a--; 9 if ((a | m) < n) { 10 res &= (~(1 << j)); 11 } 12 } 13 } 14 return res; 15 } 16 }
Single Number
寻找单独的数
思路:如果对空间没要求,可以用hashset。如果不能使用额外空间,一种非常巧妙的方法是使用异或运算。
1 public class Solution { 2 public int singleNumber(int[] nums) { 3 int res = nums[0]; 4 for (int i = 1; i < nums.length; i++) { 5 res = res ^ nums[i]; 6 } 7 return res; 8 } 9 }
Single Number II
寻找单独的数II
思路:int 数据共有32位,可以用32变量存储这N个元素中各个二进制位上1出现的次数,最后在进行模三操作,如果为1,那说明要找元素二进制表示中这一位为1。如果把3次改为k次,只需模k就行。
1 public class Solution { 2 public int singleNumber(int[] nums) { 3 int bitCount = 0; 4 int res = 0; 5 for (int i = 0; i < 32; i++) { 6 for (int j = 0; j < nums.length; j++) { 7 bitCount += (nums[j] >> i) & 1; 8 } 9 res |= (bitCount % 3) << i; 10 bitCount = 0; 11 } 12 return res; 13 } 14 }
Single Number III
寻找单独的数III
思路:只能参考discuss里面大神的思路了。。先将所有数异或,得到的结果是两个single number的异或值,然后找到任意一位为1的位提取出来(说明在这一位上这两个数一个为0一个为1),这里取出最后一位1,方法是(xor & (xor - 1)) ^ xor,这个也需要好好想一下,然后把所有的数按照这位是不是1分成两组,这样就把问题分解为两个single numberI的问题,分别异或求出即可。。
1 public class Solution { 2 public int[] singleNumber(int[] nums) { 3 int xor = 0; 4 for (int num : nums) { 5 xor = xor ^ num; 6 } 7 int bit = (xor & (xor - 1)) ^ xor; 8 int num1 = 0; 9 int num2 = 0; 10 for (int num : nums) { 11 if ((num & bit) != 0) { 12 num1 ^= num; 13 } else { 14 num2 ^= num; 15 } 16 } 17 18 int[] res = {num1, num2}; 19 return res; 20 } 21 }