137. 只出现一次的数字 II

题目:

137. 只出现一次的数字 II
面试题56 - II. 数组中数字出现的次数 II
在这里插入图片描述

题解:位运算

在这里插入图片描述

public static int singleNumber(int[] nums) {
    int a = 0;
    int b = 0;
    for(int i = 0; i < nums.length; i++)
    {
        a = (a ^ nums[i]) & ~b;
        b = (b ^ nums[i]) & ~a;
    }
    return a;
}

解释一下:假设有一个数为 x,那么则有如下规律:

常用:
x ^ 0 = x;

x ^ x = 0;

x & ~x = 0;

x & ~0 = x;

附:
x ^ 1 = ~x;

x & 0 = 0;

x & 1 = x;

那么就是很好解释上面的代码了。一开始 a = 0,b = 0;代码中的 nums[i] 即为 x。

1. x第一次出现后,a = (a ^ x) & ~b的结果为 a = x,
b = (b ^ x) & ~a的结果为b = 0。(因为此时a = x了)

2. x第二次出现:a = (a ^ x) & ~b,a = (x ^ x) & ~0,a = 0; 
b = (b ^ x) & ~a 化简,b = (0 ^ x) & ~0,b = x;

3. x第三次出现:a = (a ^ x) & ~b, a = (0 ^ x) & ~x,a = 0; 
b = (b ^ x) & ~a 化简, b = (x ^ x) & ~0,b = 0;

所以出现三次同一个数,a和b最终都变回了0.

只出现一次的数,按照上面x第一次出现的规律可知a = x, b = 0;因此最后返回a即可。

代码:位运算

public class code137 {

    public static int singleNumber(int[] nums) {
        int a = 0;
        int b = 0;
        for(int i = 0; i < nums.length; i++)
        {
            a = (a ^ nums[i]) & ~b;
            b = (b ^ nums[i]) & ~a;
        }
        return a;
    }
    
    public static void main(String[] args) {
        int nums[] = { 0,1,0,1,0,1,99 };
        int res = singleNumber(nums);
        System.out.println(res);
    }
}

参考:

  1. 只出现一次的数字 II
  2. 137. 只出现一次的数字 II(有限状态自动机 + 位运算,清晰图解)
  3. 【自动机+位运算】最详细的推导过程,没有之一
  4. 只出现一次的数字(位运算,可以推广到在多个重复n次的数字中找到出现一次的数字)
  5. 利用卡诺图生成状态转移公式,(内含对几个普遍的解法的详细解释)
  6. 详细通俗的思路分析,多解法
  7. 面试题56 - II. 数组中数字出现的次数 II(位运算 + 有限状态自动机,清晰图解)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

dev_zyx

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

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

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

打赏作者

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

抵扣说明:

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

余额充值