LeetCode 136.Single Number(只出现一次的数字)

GitHub
简书
CSDN

题目

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

说明
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?

示例1

输入: [2,2,1]
输出: 1

示例2

输入: [4,1,2,1,2]
输出: 4

难度系数: 简单

解题思路一

常规方法是,遍历数组,然后统计每个值出现的次数,最后在选择出现次数为1的那个值.该算法的时间复杂度为O(N),首先是统计数组,此时要遍历整个数组,然后是要遍历我们的统计数组,此时有事一个O(N),由于我们使用了一个统计数组来保存每个值出现的次数,此时需要的空间复杂度为O(n),因此不符合要求.

解题思路二

为了解决不需要额外的空间这个要求,我们可以使用位操作中的异或规则来进行处理.异或运算法则如下

  1. a ⊕ \oplus a = 0, a ⊕ \oplus 0=a
  2. a ⊕ \oplus b = b ⊕ \oplus a
  3. a ⊕ \oplus b ⊕ \oplus c = a ⊕ \oplus (b ⊕ \oplus c) = a ⊕ \oplus (c ⊕ \oplus b) = (a ⊕ \oplus b) ⊕ \oplus c

其中,第一条规则说明,当某个数出现两次时,通过 ⊕ \oplus 变为0,出现一次时依然保持原来的数,第二、三条的交换律和分配律说明通过多次 ⊕ \oplus 操作最终解决本题。

注意: 本体题目中指出除了某个元素值出现一次外其余的均出现两次,根据法则一可以看出本算法只适合除了某个元素出现一次外,其余元素出现偶数次的情况。

比如在示例二中的 ⊕ \oplus 操作:

4 ⊕ 1 ⊕ 2 ⊕ 1 ⊕ 2 = 4 ⊕ 1 ⊕ 1 ⊕ 2 ⊕ 2 = 4 ⊕ ( 1 ⊕ 1 ) ⊕ ( 2 ⊕ 2 ) = 4 \begin{aligned} 4 \oplus 1 \oplus 2 \oplus 1 \oplus 2 &= 4 \oplus 1 \oplus 1 \oplus 2 \oplus 2 \\ &= 4 \oplus (1 \oplus 1) \oplus (2 \oplus 2)\\ &=4 \end{aligned} 41212=41122=4(11)(22)=4

Java实现代码

/**
 * @author Maosong Ran
 * @date 2018/10/06
 * @email maosongran@gmail.com
 */
public class LeetCode_136 {
    public int singleNumber(int[] nums) {
        int result = 0;
        int len = nums.length;
        for (int i=0; i < len; ++i)
            result ^= nums[i];
        return result;
    }

    public static void main(String[] args) {
        LeetCode_136 leetCode = new LeetCode_136();
        System.out.println(leetCode.singleNumber(new int[]{2, 2, 1}));
        System.out.println(leetCode.singleNumber(new int[]{4, 1, 2, 1, 2}));
    }
}

输出:

1
4

致谢

感谢大家的阅读和支持, 欢迎大家上星..

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值