Java编程题目-9:find the single number

这道题也是LeetCode上的题目,但是我没能自己做出来。悲伤脸。。题目链接
题目限定的是给一个数组,里面的元素都是成对出现的,但是出了一个不是。
题目要求就是不使用额外的空间线性的时间复杂度找出那个不成对的元素。
比如数组:arr = {1,1,2,2,3},我们要找到3这个元素并返回。
这道题目我想了好久,也没能找到满足题目要求的“不使用额外的空间”、“线性的时间复杂度”这两个要求。最终,我只能去研究别人的代码,发现大神们使用xor(异或)就完美解决了这个问题。
代码如下:

public class Solution {
    public int singleNumber(int[] nums) {
        int res = 0;
        for(int i=0;i<nums.length;i++) res^=nums[i];
        return res;
    }
}

这个代码十分简洁,但是里面的思想一般还真难想到—将数组元素进行连续的异或。


下面来分析下代码执行过程:

  1. 比如说传给方法的参数是{1,1,2,2,3}
  2. for循环当中的res^=nums[i]就等价于nums[0]^nums[1]^nums[2]^nums[3]^nums[4]
  3. 也就是:1^1^2^2^3
  4. 异或的运算结果就要考虑二进制了,将元素(1,2,3)转换成二进制进行异或运算
  5. 01^01^10^10^11,其中01^01=00,00^10=10,10^10=00,00^11=11
    也就是累计异或运算后得到二进制结果是11,也就是3。

上面的计算可以得到下面几点:

  1. 任何数与0异或都得到其自身
  2. 任何数与自身异或都得到0
  3. 异或满足交换律
    所以,在成对的元素中找出唯一不成对的那个,使用异或是最有效的手段。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值