0260. Single Number III (M)

Single Number III (M)

题目

Given an array of numbers nums, in which exactly two elements appear only once and all the other elements appear exactly twice. Find the two elements that appear only once.

Example:

Input:  [1,2,1,3,2,5]
Output: [3,5]

Note:

  1. The order of the result is not important. So in the above example, [5, 3] is also correct.
  2. Your algorithm should run in linear runtime complexity. Could you implement it using only constant space complexity?

题意

给定一个数组,其中只有两个数只出现了一次,其他所有数都出现了两次。要求找出这两个数。

思路

  1. 最简单的做法就是使用Set进行操作,将已出现过的从Set中除去,将未出现过的加入到Set中。最后留下的就是要找的两个数。

  2. 与 0136. Single Number 使用的方法相同,用异或找出这两个数a和b,具体方法如下:

    1. 对所有数进行异或,得到的结果就是a和b的异或(相同的数异或会抵消得到0),记为xor。
    2. 因为a和b是不同的数,所以它们二进制的某一位必定不一样,从右到左找到xor中第一个1(相当于从右到左找到a和b二进制第一个不同的位),记为pos。如:3 ^ 5 = 011 ^ 101,pos = 010。
    3. 将nums中所有的数与pos相与,可以将结果分为两组,区别在于对应二进制位上的数不同,而a和b一定分属于这两个组。
    4. 接着问题就变成和136一样的情况,将两组数分别异或,得到的就是a和b。

代码实现

Java

Set

class Solution {
    public int[] singleNumber(int[] nums) {
        Set<Integer> set = new HashSet<>();
        for (int num : nums) {
            if (set.contains(num)) {
                set.remove(num);
            } else {
                set.add(num);
            }
        }
        int[] ans = new int[set.size()];
        int index = 0;
        for (int num : set) {
            ans[index++] = num;
        }
        return ans;
    }
}

位操作

class Solution {
    public int[] singleNumber(int[] nums) {
        int[] ans = new int[2];
        int xor = 0;
        for (int num : nums) {
            xor ^= num;
        }
        int pos = 1;
        while ((xor & pos) == 0) {
            pos <<= 1;
        }
        for (int num : nums) {
            if ((num & pos) == 0) {
                ans[0] ^= num;
            } else {
                ans[1] ^= num;
            }
        }
        return ans;
    }
}

JavaScript

/**
 * @param {number[]} nums
 * @return {number[]}
 */
var singleNumber = function (nums) {
  let xor = 0
  for (let num of nums) {
    xor ^= num
  }
  let pos = 1
  while (!(pos & xor)) {
    pos <<= 1
  }
  let a = 0
  let b = 0
  for (let num of nums) {
    if (num & pos) {
      a ^= num
    } else {
      b ^= num
    }
  }
  return [a, b]
}

参考

LeetCode 260. Single Number III 题解

上一篇:leetcode260 Single Number III


下一篇:剑指offer,二叉树的下一个节点