算法:碰到位运算算法就不会?帮你巧用位运算解题

位运算的概念

  • 按位与 a & b :两个位都为1,结果才为1

  • 按位或 a | b :两个位有一个为1,结果就为1

  • 按位异或 a ^ b :相同为0,不同为1

  • 按位取反 ~a :0变1,1变0

  • 左移 a << b :相当于a乘以2的b次方

  • 右移 a >> b :相当于a除以2的b次方

  • 无符号数右移 a >>> b

算法题

方法

一些题的方法要记熟:

  • n ^ n = 0;

  • n ^ 0 = n;

  • 判断是否是2的幂

  • 判断1的个数

  • 交换两个数字

下下策:

  • 可以使用Integer.toBinaryString(int i)将二进制转换成字符串进行求解

LeetCode简单题

231. 2 的幂

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

给你一个整数 n,请你判断该整数是否是 2 的幂次方。如果是,返回 true ;否则,返回 false

如果存在一个整数 x 使得 n == 2x ,则认为 n 是 2 的幂次方。

解题:如果n&n-1 == 0,n是2的幂

 //注意返回值要用括号括起来,要不可能因为优先级而报错
 class Solution {
     public boolean isPowerOfTwo(int n) {
         return n>0 && (n & (n-1)) == 0;
     }
 }

342. 4的幂

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

解题:一直上一题求2的幂的思路,那么这一题我们只需要加一个条件判断 是2的幂不是4的幂的情况

我们发现 能被3求余 == 1的数就是4的幂,那么加上n%3==1这个条件即可,其实同理n%7 == 1的和8有关

 class Solution {
     public boolean isPowerOfFour(int n) {
         return n>0 && (n&(n-1))==0 && n%3==1;
     }
 }

191. 位1的个数

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

题解:这一题的方法有很多种

1.使用位运算,把n往右移32次,每次都和1进行与运算。可以优化成递归。

2.使用内置方法Integer.bitCount

3.使用toString(2)

 //1.使用位运算
 public int hammingWeight(int n) {
     int count = 0;
     for (int i = 0; i < 32; i++) {
         if ((n & 1) == 1) count++;
         n = n >> 1;
     }
     return count;
 }
   //可以优化成递归
 public static int hammingWeight(int n) {
     if (n == 0) return 0;
     return (n & 1) + hammingWeight(n >>> 1);
   //return n==0?0:(n & 1) + hammingWeight(n >>> 1);
 }
 ​
 //2.使用内置方法 Integer.bitCount
 public int hammingWeight(int n) {
     return Integer.bitCount(n);
 }
 ​
 ​
 //方法3.使用 toString(2)
 public int hammingWeight(int n) {
     String str = Integer.toBinaryString(n);
     int count = 0;
     for (char i:str.toCharArray()){
         if (i=='1') ++count;
     }
     return count;
 }

LeetCode中等

重要:16.01. 交换数字

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

题意:编写一个函数,不用临时变量,直接交换numbers = [a, b]ab的值。

这个题很重要了,有的时候我们写题需要swap(),而我们自己写就可以用这种方法,来给面试官装一个。

题解:抑或的一些特殊情况:a^a == 0 a^0 == a

把一句话代码带入第二句话 : numbers[1] = numbers[0]^numbers[1] = numbers[0]^numbers[1] ^ numbers[1] = numbers[0];

把二句话代码带入第三句话 : numbers[0] = numbers[0]^numbers[1] = numbers[0] ^ numbers[0]^numbers[1] = numbers[1];

 public int[] swapNumbers(int[] numbers) {
     numbers[0] = numbers[0]^numbers[1];
     numbers[1] = numbers[0]^numbers[1];
     numbers[0] = numbers[0]^numbers[1];
     return numbers;
 }

重要:371. 两整数之和

链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

题意:不用+号,求两个整数之和

解题:

  • ^表示的是相同为0,不同为1,其实就是不带进位的加法

  • 而当都为1的时候才需要进位

 public int getSum(int a, int b) {
     return b==0?a:getSum(a^b,(a&b)<<1);
 }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

shn!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值