位运算
知识:
亦或:1.不进位加法,A^0=A,A^A=0;2.满足结合律,交换律;3.结果与先后顺序无关
位运算专题:
1. 2的幂:如何判断一个数是不是2的幂次方?将一个数用二进制表示,如果整个数字只有一个2,那就是2的幂次方;如果有不止一个2,那就不是2的幂次方。那么问题就简单了,将这个数的二进制的最后一位除去,剩下的数如果是0,那就是2的幂次方。题目:leetcode 231。
class Solution { public: bool isPowerOfTwo(int n) { return ((n>0) && ((n & (n-1)) == 0)); } };
注意一点:return 后面的逻辑语句的顺序不能搞反,不然过不了
注意一点:2的幂次方一定是一个正数,最小是1
注意一点:这种rerurn 一个逻辑表达式的方式一定学会,不要再if(A)rerurn 1;else return 0;了,显得你很不专业
2. 4的幂次方:如何判断一个数是不是4的幂次方?根据初等数论的知识,我们可以知道4的幂次方等价于以下两个条件:
1.是2的幂次方 2.%3==1
题目:Leetcode342
class Solution { public: bool isPowerOfFour(int n) { return ((n>0) && ((n & (n-1)) == 0) && (n % 3 == 1)); } };
错误答案:
class Solution { public: bool isPowerOfFour(int n) { return ((n>0) && ((n & (n-1)) == 0) && (n % 3 == 1)); } };
少了红色的括号,就错了
3. 位1的个数:依旧是与运算
lc191,代码:
class Solution { public: int hammingWeight(uint32_t n) { int cnt=0; while(n){ n &= (n-1); cnt++; } return cnt; } };
4. 交换数字:
异或运算:相当于不进位的加法运算,A ^ 0 = A, A ^ A = 0 ,满足交换律和结合律。题目 lc16.01
class Solution { public: vector<int> swapNumbers(vector<int>& numbers) { numbers[0] = numbers[0] ^ numbers[1]; numbers[1] = numbers[0] ^ numbers[1]; numbers[0] = numbers[0] ^ numbers[1]; return numbers; } };
5. 只出现一次的数字:
最基础的位运算应用,使用异或运算的性质。lc136:
class Solution { public: int singleNumber(vector<int>& nums) { int x = nums[0] , n = 1; while(n < size(nums)){ x ^= nums[n]; n++; } return x; } };
注意:-= 只能写成-=,不能写成 - = ,中间不要留个空格听到没?
6. 汉明距离:两个数字的二进制有几位不同,它们的汉明距离就是多少。这时就要用到异或运算的性质。毕竟以后运算不同则1。lc461
class Solution { public: int hammingDistance(int x, int y) { int n = 0; int temp = x ^ y; while(temp){ temp &= (temp - 1); n++; } return n; } };
7. 交替位二进制数:lc693
class Solution { public: bool hasAlternatingBits(int n) { long a = n ^ (n >> 1); return (a & (a + 1)) == 0; } };
8. 两整数之和!lc371,使用递归计算
class Solution { public: int getSum(int a, int b) { if (b == 0)return a; return getSum(a ^ b,(unsigned int)(a & b) << 1); } };
错误:
class Solution { public: int getSum(int a, int b) { if (a == 0)return b; return getSum(a ^ b,(unsigned int)(a & b) << 1); } };
不知道为什么错误