LeetCode 260.只出现一次的数|||【Java】

1. 题目

给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。你可以按 任意顺序 返回答案。
示例 1:
输入:nums = [1,2,1,3,2,5]
输出:[3,5]
解释:[5, 3] 也是有效的答案。

示例 2:
输入:nums = [-1,0]
输出:[-1,0]

示例 3:
输入:nums = [0,1]
输出:[1,0]

2.思路与代码

这道题需要运用到异或^

异或的性质:

  • 相同则0不同则1
  • 恒等律:X ⊕ 0 = X
  • 归零律:X ⊕ X = 0
  • 交换律:A ⊕ B = B ⊕ A
  • 结合律:(A ⊕ B) ⊕ C= A ⊕ (B⊕ C)

根据异或的性质,我们可以知道有两个的数相互异或最后等于0

A ^ B ^ C ^ B ^ C ^ D ^ A
= A ^ A ^ B ^ B ^ C ^ C ^ D
= 0 ^ 0 ^ 0 ^ D
= 0 ^ D
= D

当要要查找的数字只有一个时,只需要所有数全部异或即可。 只出现一次的数

同样适用于其余数出现偶数次,找出出现奇数次的数

那当出现奇数次的数有两个怎么求解?

我们依旧将所有数异或:

A ^ B ^ C ^ B ^ C ^ D ^ A ^ E
= A ^ A ^ B ^ B ^ C ^ C ^ D ^ E
= 0 ^ 0 ^ 0 ^ D ^ E
= 0 ^ D ^ E
= D ^ E

最后得出的数是两个剩下的数的异或

此时题目就更改成了:

已知两个数的异或,怎么求出这两个数?

EOR = D ^ E,根据异或的性质可得出:D = EOR ^ E ,所以我们只需找到DE其中一个数,就可以找到另外一个数

DE两个数唯一已知的就是两个数不可能是一个数值,所以所求的异或肯定存在一位是1,假设这位数是8则D ^ E = 10000000,说明DE两个数的第八位是不同的。

剩下的就很简单了:我们只需要将所有的第八位等于1或者0的所有数异或,就能得到D或者E其中一个

关于如何找到DE两个数不同的位数:
下图是关于如何找到右侧第一个1
在这里插入图片描述
看左神的视频里学到的orz,属实离谱

代码:

class Solution {
    public int[] singleNumber(int[] nums) {
        int eor = 0;
        for(int tmp:nums){
            eor ^= tmp;
        }
        int rightNum = eor & (~eor + 1);//找到最右侧的1
        int eor1 = 0;
        for(int tmp:nums){
            if((rightNum & tmp) == 0){
                eor1 ^= tmp;
            }
        }
        int[] tmp = new int[2];//这个数组没必要,可以直接在nums写
        tmp[0] = eor1;
        tmp[1] = eor1^eor;
        return tmp;
    }
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值