剑指 Offer 56 - I. 数组中数字出现的次数

该博客介绍了如何解决力扣上的一个问题——找出数组中仅出现一次的两个数字。博主通过解析解题思路和提供两种不同的代码实现(HashMap统计法和异或位运算法),详细阐述了如何利用位操作找出这两个数字。核心在于理解异或运算的性质,以及如何通过位运算找到两个数字的不同位来区分它们。
摘要由CSDN通过智能技术生成

力扣打卡:剑指 Offer 56 - I. 数组中数字出现的次数

解题思路

首先遍历一遍数组后,得到的是xor,也就是两个元素的异或结果

此时对xor取值,在xor的二进制中,数值为1的位置都是 a 和 b 的不同位置形成的,(相同为0,不同为1)
那么通过这个来区分数组中的元素,因为数组中的每一个元素要么在这个位置上为1,要么在这个位置上为0,所以分为两类
但是数组中的元素不对结果造成任何影响,因为数组中的元素都是出现了偶数次,异或的结果会将其抵消了

最终所剩下的结果就是两个出现一次的结果

代码

class Solution {
    public int[] singleNumbersA(int[] nums) {
        // 使用HashMap进行统计
        HashMap<Integer,Integer> map = new HashMap<>();
        for(int i: nums){
            map.put(i,map.getOrDefault(i,0)+1);
        }
        int[] ans = new int[2];
        int i = 0;
        for(Map.Entry<Integer,Integer> entry : map.entrySet()){
            if(entry.getValue()==1) ans[i++] = entry.getKey();
        }
        return ans;
    }
    // 重点理解异或位运算
    public int[] singleNumbers(int[] nums) {
        int xor = 0;
        for(int i: nums){
            xor ^= i;
        }
        int[] ans = new int[2];
        // 此时的 xor 为 两个出现一次的元素的异或结果
        int diff = xor & (~xor+1);// 按位取反后,再进行加1,此时能够取出最后一个1到末尾的二进制串
        for(int i: nums){
            if((i&diff)==0) ans[0]^=i;
            else ans[1] ^= i;
        }
        return ans;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值