剑指 Offer 65. 不用加减乘除做加法
菜鸡思路:
比如5 + 6
相当于拆成二进制来运算:
1 0 1
+ 1 1 0
一个1一个0不进位,两个1进位。
菜鸡代码:
class Solution {
public:
int add(int a, int b) {
while (b) {
int carry = a & b; // 计算 进位的地方
a = a ^ b; // 计算 本位
b = (unsigned)carry << 1;//前移进位
}
return a;
}
};
剑指 Offer 15. 二进制中1的个数
菜鸡思路:
对每一位按位与,不为零,就是1。
菜鸡代码:
class Solution {
public:
int hammingWeight(uint32_t n) {
int ret = 0;
for (int i = 0; i < 32; i++) {
if (n & (1 << i)) {
ret++;
}
}
return ret;
}
};
剑指 Offer 56 - I. 数组中数字出现的次数
思路:
感觉位运算都像智力题似的,直接看题解吧:
先对所有数字进行一次异或,得到两个出现一次的数字的异或值。
在异或结果中找到任意为 1的位。
根据这一位对所有的数字进行分组。
在每个组内进行异或操作,得到两个数字。
代码:
class Solution {
public:
vector<int> singleNumbers(vector<int>& nums) {
int ret = 0;
for (int n : nums) {
ret ^= n;
}
//ret最终答案就是那两个只出现一次的的数异或的结果
int div = 1;
//找到ret二进制数中第一个1
while ((div & ret) == 0) {
div <<= 1;
}
int a = 0, b = 0;
for (int n : nums) {
if (div & n) {//第一组
a ^= n;
} else {//第二组
b ^= n;
}
}
return vector<int>{a, b};
}
};
剑指 Offer 56 - II. 数组中数字出现的次数 II
思路:
乍一看非常困难,但是看了别人的思路就能想通
代码:
class Solution {
public:
int singleNumber(vector<int>& nums) {
int bits[32] = {0};
for (int i = 0; i < nums.size(); i++) {
int j = 0;
//得到各个二进制位为1的有多少个
while (nums[i]) {
bits[j] += nums[i] % 2;
nums[i] /= 2;
j++;
}
}
int ans = 0;
for (int i = 0; i < 32; i++) {
//利用%3 来求得对应位置上有没有1 有的话乘对应的 2 的i次方
ans += (1 << i) * (bits[i] % 3);
}
return ans;
}
};