Leetcode刷题(Week2)—— 位运算

题号题目链接
89Gray Codehttps://leetcode.com/problems/gray-code/
137Single Number IIhttps://leetcode.com/problems/single-number-ii/
371Sum of Two Integershttps://leetcode.com/problems/sum-of-two-integers/
191Number of 1 Bitshttps://leetcode.com/problems/number-of-1-bits/
461Hamming Distancehttps://leetcode.com/problems/hamming-distance/
36Valid Sudokuhttps://leetcode.com/problems/valid-sudoku/
50Pow(x, n)https://leetcode.com/problems/powx-n/
190Reverse Bitshttps://leetcode.com/problems/reverse-bits/

解体心得

No.89 格雷码 (AC)

  • 格雷码的特点: 没两个相邻的格雷码仅有一位不同
  • 格雷码的生成方式:1.递归生成: 当格雷码只有1位时,分别是0,1; 当格雷码为两位时,前2个格雷码是在0,1前加0前缀(00,01),后两个格雷码是加前缀1,同时将0,1反序(11,10),以此类推; 2. 异或生成 由二进制码生成格雷码是,从左边数第二位开始,Bi与Bi-1的异或是格雷码第i位上的值;
  • 有格雷码反编码二进制码是:从左边数第二位开始,Bi与Bi-1的异或是二进制码第i位上的值。

No.137 唯一只出现一次的数字 (AC)(划重点)

  • 本题需要特别注意有负数的情况
  • 先统计32位每一位上数字出现的次数。然后看每一位是不是3的倍数,若不是,则该位是单独那个数字对应的位。找到单独的数字对应的所有位之后,即可将这个只出现一次的数字求出来。
  • 关键问题是怎么求这个只出现一次的数字:
  • Bug方法是: res += pow(2, i); 这种方法在有负数的情况下会出bug
  • 正确方法: 完全用位运算实现,res += (n[i] % 3) << 1; 这里n[i] % 3只可能是0或1,因此这里完全可以这样做,这样在有负数情况下也完全成立。

No.371 求两数之和 (AC)

  • 参考题解: https://www.acwing.com/solution/LeetCode/content/543/
  • 两数相“异或”,得到基本位;两数相“与”,得到进位。进位在做二次加法的时候需要左移以为再使用。需要特别注意的一点是, 存在为负的情况。 左移操作需要将原本进位的值转换成无符号数。
  • 补充: 一个数的补码= 原二进制数按位取反后加1。由补码啊得到其真正表示的数,方法是先-1, 再按位取反。

No.191 计算一个数的二进制表示中1的个数 (AC)

  • L按位循环32次,统计每一位是否为1. 具体方法是: if (n >> i & 1 != 0) res++; 这里n >> i & 1的含义是n右移i位后和000000000000000000000000000000000001做与运算,其实也就是判断n右移i位后的最后1位是否为1.

No.461 求两个int类型的整数二进制位的值不相同的共有几位

  • 按位枚举。
  • x >> 10 & 1用于求x的第10位的值是0还是1

No.36 判断数独板是否行列和3*3区域都不包含重复1~9的数

  • 位运算简化计算
  • 用三个vector数组表示行、列和3*3区域中1~9是否有值
  • row[i] |= (1 << num);

No.50 幂运算 (AC)

  • 快速幂优化解题速度,时间复杂度:logn
  • 对于指数n, 现将其转换成正数,需要注意的是当 n = INT_MIN时, 用ans(n)会爆int,解决方法是,先用一个long类型的变量t存储n,再做接下来的操作
  • 对于n分析其每一位二进制位是否为1, 若为1, 则乘于相应base,每循环一次,base自乘。
for( ; t; t >>= 1){
     if (t & 1){
         ans *= base;
     }
     base *= base;
 }

No.190 翻转一个数的二进制表示 (AC)

  • 循环32位,一次取出最低位,成为答案的最高位。
  • res = (res << 1) + (n >> i & 1);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值