美文网首页每周算法
LeetCode 136.Single Number(只出现一次

LeetCode 136.Single Number(只出现一次

作者: MaosongRan | 来源:发表于2018-10-06 15:19 被阅读0次

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 操作:

\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}

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

致谢

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

相关文章

网友评论

    本文标题:LeetCode 136.Single Number(只出现一次

    本文链接:https://www.haomeiwen.com/subject/pfshaftx.html