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:

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

    分析

本题是有两个未知数,是 "Single Number" 这道题的扩展,直接做异或肯定是不行的。有没有办法把两个未知数分开,使得可以应用Single Number 的解法呢?

x, y是那两个未知数,那么如果对这个数组做异或的话,结果实质上等于x ^ y,因为其他数都出现了两次,被抵消了。

但是仅仅是通过最后异或出来的值,是没办法区分出xy的,但是足以帮助我们把xy划分到不停地子数组中去。对于xy,由于二者不相等,那么二者至少存在一位不相同,如下图所示:

 Single Number III  - 图1

当找到这个k以后,就可以按照第k位是否等于1,将nums数组划分为两个子数组,然后把Single Number的算法直接应用到两个子数组上,就可以求出xy了。

代码

  1. // Single Number III
  2. // Time Complexity: O(log n), Space Complexity: O(1)
  3. public class Solution {
  4. public int[] singleNumber(int[] nums) {
  5. int xorResult = 0;
  6. for (int x : nums) {
  7. xorResult ^= x;
  8. }
  9. // get the index of first 1
  10. int k = 0;
  11. for (k = 0; k < Integer.SIZE; ++ k) {
  12. if (((xorResult >>> k) & 1) == 1) {
  13. break;
  14. }
  15. }
  16. // use k to split the array into two subarrays
  17. // XOR result of the first subarray
  18. int xorResult2 = 0;
  19. for (int x : nums) {
  20. if (((x >>> k) & 1) == 1) {
  21. xorResult2 ^= x;
  22. }
  23. }
  24. return new int[] {xorResult2, xorResult ^ xorResult2};
  25. }
  26. }

原文: https://soulmachine.gitbooks.io/algorithm-essentials/content/java/bitwise-operations/single-number-iii.html