260. Single Number III (找到数组中仅出现一次的两个数)

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.

For example:

Given nums = [1, 2, 1, 3, 2, 5], return [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:HashSet,遍历数组,把每个元素都放入hashset中,如果hashset中已经存在这个元素,则将这个元素移除,最后hashset中剩余的两个数就是要找的那两个数。代码如下:(10ms,beats 21.25%)

public int[] singleNumber(int[] nums) {
        Set<Integer> set = new HashSet<>();
		int[] res = new int[2];
		int index = 0;
		for (int num : nums) {
			if (!set.add(num))
				set.remove(num);
		}
		Iterator<Integer> it = set.iterator();
		while (it.hasNext())
			res[index++] = it.next();
		return res;
    }


解法二:题目要求只使用常数数量级的额外存储空间,则不使用解法1。可以使用位运算,计算数组中所有元素的异或值xor,由于数组中除了某两个数a、b,其他数都出现了两次,那么xor其实就为 a^b 。现在计算lowest = xor & (-xor),lowest的含义是从最低位开始取 xor 二进制表示中第一个‘1’所对应的值,假设xor = a^b = 12(即1100),则lowest = 4(即0100),那么说明在 从最低位开始 的第三位上,a和b对应的值一定不相同。那么a&lowest != b&lowest。那么解法就是:令a=b=0,对于数组中的每一个数num,如果num&lowest==0,则a^=num,否则b^=num。最后得到的a、b就是要求的那两个数。代码如下:(1ms,beats 78.47%)

public int[] singleNumber(int[] nums) {
		int[] res = new int[2];
		int xor = 0, lowest, a = 0, b = 0;
		for (int num : nums)
			xor ^= num;
		lowest = xor & (-xor);
		for (int num : nums) {
			if ((num & lowest) == 0)
				a ^= num;
			else
				b ^= num;
		}
		res[0] = a;
		res[1] = b;
		return res;
	}


你可能感兴趣的:(LeetCode,算法,位操作)