算法中常见的两个操作
1.位与操作(n & (n-1))
作用:消除一个数n的二进制表示中的最后一位1
举个栗子:
数n和数n-1:
位 | … | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|
n | … | 1 | 0 | 1 | 0 | 0 |
n-1 | … | 1 | 0 | 0 | 1 | 1 |
那么n & (n-1)的值二进制表示就是 10000
利用n & (n-1)可以解决一些简单的Leetcode上的题目
如:Leetcode 剑指 Offer II 003. 前 n 个数字二进制中 1 的个数 等
附上代码
class Solution {
public:
int checkBits(int num){
int count = 0;
while(num != 0)
{
num &= num - 1;
count++;
}
return count;
}
vector<int> countBits(int n) {
vector<int> v(n+1);
for(int i = 0; i <= n ; ++i)
{
v[i] = checkBits(i);
}
return v;
}
};
当然,如果你会动态规划,这题还要更优的解法。
2.异或操作 (n ^ 0 = n)
异或操作性质如下:
0与任何数异或得任何数:0⊕number = number
两个相同的数相异或等于0:number ⊕ number = 0
异或运算满足交换律和结合律:
a ⊕ b ⊕ a == a ⊕ a ⊕ b = 0 ⊕ b = b
a ⊕ 0 ⊕ a == a ⊕ (0 ⊕ a) = a ⊕ a = 0
例如: Leetcode136. 只出现一次的数字 等
题目描述:
给你一个 非空 整数数组nums
,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。你必须设计并实现线性时间复杂度的算法来解决此问题,且该算法只使用常量额外空间。
代码:
class Solution {
public:
int singleNumber(vector<int>& nums) {
int result = 0;
for(auto &a :nums)
{
result ^= a;
}
return result;
}
};