算法题解之位运算

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 }
View Code

 

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 }
View Code

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 }
View Code

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 }
View Code
原文地址:https://www.cnblogs.com/coldyan/p/6047264.html