栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java之位运算符在算法中的简单应用(附算法题:只出现一次的数字)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java之位运算符在算法中的简单应用(附算法题:只出现一次的数字)

位运算符有

  • &
    按位与
    如果两个相应的二进制位都为1,则该位的结果值为1,否则为0
  • |
    按位或
    两个相应的二进制位中只要有一个为1,该位的结果值为1
  • ^
    按位异或
    若参加运算的两个二进制位值相同则为0,否则为1
  • ~
    取反
    ~是一元运算符,用来对一个二进制数按位取反,即将0变1,将1
  • <<
    左移
    用来将一个数的各二进制位全部左移N位,右补0
  • >>
    右移
    将一个数的各二进制位右移N位,移到右端的低位被舍弃,对于无符号数, 高位补0(正数)或1(负数)
  • >>>
    右移
    将一个数的各二进制位右移N位,移到右端的低位被舍弃,对于无符号数, 高位补0
今天遇到的题目是这样的:

class Solution {
    public int[] singleNumber(int[] nums) {
        int xorsum = 0,a=0,b=0;
        for (int num : nums) {
            xorsum ^= num;
        }
      int div=1;
      while((xorsum & div)==0){
          div=div<<1;
      }
      for(int i=0;i 

知识基础:a ^ b ^ b=a,且满足结合律和分配律(b ^ a ^ b=a),故相同的数是可以直接消除的。很容易得到最后两个不同数字的^(异或)结果。所以关键是怎么区分他们呢?
先说实例:3(0011),5(0101)
3^5=0110(6),我就可以用倒数第二位的那个1作为3跟5的区别对他们进行不同的分组,用0010和3(0011)做&与运算,得到的是0010(非0)。用0010和5(0101)做&与运算,得到的是0000(为0)。

再说道理:两个数的异或值中,为1的那几位数就是这两个数的不同点,只要找到是第几位为1,然后用这个位数跟这两个数进行与运算,得到的值一定不同。

  1. 将数组每个值都进行异或运算,相同的为0,最后得到的就是那两个独立的值的异或结果记为xorsum。
  2. 数字1(div)的二进制为0001,用它末尾的那个1与xorsum进行&与运算,得到为0,说明xorsum的最后一位为0,我们要找到xorsum中为1的那一位,所以让数字1进行左移<<,重复判断得到div(例如可能是0010),用div这个数与数组元素进行与运算,就可以把需要找的那两个数分开为两组了。

可能说的不是太清楚,但我真的尽力了,只能说我自己心里清楚了,位运算确实有点东西。我第一想法其实是用HushMap做的,但空间复杂度有点高。

最后有个更难理解的题,:

class Solution {
    public int singleNumber(int[] nums) {
        int ans = 0;
        for (int i = 0; i < 32; ++i) {
            int total = 0;
            for (int num: nums) {
                total += ((num >> i) & 1);
            }
            if (total % 3 != 0) {
                ans |= (1 << i);
            }
        }
        return ans;
    }
}

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/WGki4K/solution/zhi-chu-xian-yi-ci-de-shu-zi-by-leetcode-0vrt/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。



我感觉还是HushMap更好理解,哭唧唧

class Solution {
    public int singleNumber(int[] nums) {
        Map freq = new HashMap();
        for (int num : nums) {
            freq.put(num, freq.getOrDefault(num, 0) + 1);
        }
        int ans = 0;
        for (Map.Entry entry : freq.entrySet()) {
            int num = entry.getKey(), occ = entry.getValue();
            if (occ == 1) {
                ans = num;
                break;
            }
        }
        return ans;
    }
}

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/WGki4K/solution/zhi-chu-xian-yi-ci-de-shu-zi-by-leetcode-0vrt/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/362339.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号