位运算第一弹

简介: 位运算第一弹

1.基础位运算

191 338 461

<<   左移

&按位与      有0就是0

>>   右移

||按位或      有1就是1

~     按位取反

^按位异或  

相同为0,不同为1,无进位相加(正常1+1是前进,但是他不进行进位)

位运算的优先级,能加括号,就加括号,这样最不容易出错

这个取反,相当于是个简单操作,就是开始把所有都是0,然后把1放在x的位置,然后,再一个取反。

位图的思想

异或运算的运算律

a^0=a

a^a=0

a^b^c=a^(b^c)

偶数全部会被干掉,只剩一个奇数

引入题目

力扣136.只出现一次的数字

这题的审题,首先看他是只有一个数字是单独一个的,其他的数字都是两个

异或的本质就是相加的时候,不去进位,相当于消消乐,偶数就消去

class Solution {
    public int singleNumber(int[] nums) {
      int ret=0;
      for(int x:nums){
          ret=ret^x;
      }
      return ret;
    }
}

力扣260.只出现一次的数字III

     s = 101100
    ~s = 010011
(~s)+1 = 010100 // 根据补码的定义,这就是 -s   效果:s 的最右侧的1(也叫最低位)左侧取反,右侧不变
s & -s = 000100 // lowbit
    
链接:https://leetcode.cn/problems/single-number-iii/solutions/2484352/tu-jie-yi-zhang-tu-miao-dong-zhuan-huan-np9d2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

首先先导入知识

这个题解说的很细,很吊

首先:他不可能最后异或的结果全部是0,因为有两个不同的数字,所以,最后肯定有一个数是1,那么就肯定是有一个是0,有一个是1。

那么假如极端点,全部都是1,比如1111

例如0000^1111其他的我们不去关注,因为全部都会出现两个。

所以我们都使用这个保留最后一个1的方式。

然后我们进行什么操作呢?

->把最后那个为1的位,我们进行分组,因为最后是1,所以那两个单独的肯定是一个0,一个1,其余的我们不用操心,我总是担心什么出现5个1,3个0,但是这么想没有必要,到最后还是

分组成0和1,最后我们用这个&来分组,把那个位置为0的和为1的区分开来,哪怕只有一个是0,有999个1,那也是区分开来,然后有一个是单独的。

class Solution {
    public int[] singleNumber(int[] nums) {
    int[]ret=new int[2];
    Arrays.sort(nums);
    int m=0;
    int count=0;
   for(int x:nums){
       m=m^x;
   }
   int lowbit=m&-m;
   for(int x:nums){
       ret[(lowbit & x)== 0?0:1]^=x;
   }
    return ret;
    }
}


相关文章
|
2月前
|
消息中间件 Kubernetes NoSQL
剑指offer常见题 - 位运算问题(二)
剑指offer常见题 - 位运算问题(二)
|
2月前
|
消息中间件 Kubernetes NoSQL
剑指offer常见题 - 位运算问题(一)
剑指offer常见题 - 位运算问题(一)
|
1月前
|
算法
二分查找第一弹
二分查找第一弹
|
1月前
|
索引
二分查找第二弹
二分查找第二弹
|
1月前
|
存储
位运算第二弹
位运算第二弹
|
1月前
|
存储
前缀和第二弹
前缀和第二弹
|
1月前
前缀和第一弹
前缀和第一弹
|
2月前
|
C语言
每天一道C语言编程(第一弹~):数组
每天一道C语言编程(第一弹~):数组
21 0
|
7月前
|
C语言