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?

链接: http://leetcode.com/problems/single-number-iii/

题解:

昨晚卡到现在。但昨晚睡觉前google了一下,看到了几篇文章以后才理解。还是需要加强bit manipulation。 归根结底是大学时数字电路没学好 -_____-!! 我不堪的本科生涯...略去一亿字。

这里我们主要是先异或所有数字,得到 a^b, 因为a和b不相等,所以 a^b里至少有一个bit位k,k = 1。 然后我们就可以用这个第k位来进行判断, 因为a和b里只有一个数第k位 = 1,我们对输入数组所有第k位为1的数字进行异或,就可以找到第k位为1的仅出现一次的数字, 再用这个数字a和 a^b进行异或,我们也就求得了b。

Time Complexity - O(n), Space Complexity - O(1)。

public class Solution {
    public int[] singleNumber(int[] nums) {
        int[] res = {-1, -1};
        if(nums == null || nums.length == 0) {
            return res;
        }
            
        int a_XOR_b = 0;  
        for(int i = 0; i < nums.length; i++) {      // find a ^ b
            a_XOR_b ^= nums[i];
        }
        int k = 0;                              // find one bit in a^b == 1
        for(int i = 0; i < 31; i++) {           // that means only one num in a, b has 1 on kth bit
            if(((a_XOR_b >> i) & 1) == 1) {
                k = i;
                break;
            }
        }
        int a = 0;
        for(int i = 0; i < nums.length; i++) {   // since only one num in a, b has 1 on kth bit
            if(((nums[i] >> k) & 1) == 1) {      // we can XOR all nums has 1 on kth bit
                a ^= nums[i];                    // duplicate nums will be evened out
            }
        }
        int b = a ^ a_XOR_b;
        res[0] = a;
        res[1] = b;
        return res;
    }
}

二刷:

也是用一刷一样的方法,比较tricky

Java:

public class Solution {
    public int[] singleNumber(int[] nums) {
        int[] res = {-1, -1};
        if (nums == null || nums.length == 0) {
            return res;
        }
        int a_XOR_b = 0;
        for (int i : nums) {
            a_XOR_b ^= i;
        }
        int k = 0;
        for (int i = 0; i < 32; i++) {
            if (((a_XOR_b >> i) & 1) == 1) {
                k = i;
                break;
            }
        }
        res[0] = 0;
        for (int i : nums) {
            if (((i >> k) & 1) == 1) {
                res[0] ^= i;
            }
        }
        res[1] = a_XOR_b ^ res[0];
        return res;
    }
}

题外话:  

其实本科时,学校开设的课程挺不错的,老师也努力务实,都怪自己没把心思放在学习上。虽然专业是EE,但像什么基数排序,霍夫曼编码,游程码,最短路径之类的东西,老师们也都多少介绍过。信息量很大,作业和考试也难。真要四年扎扎实实学下来的话,也不至于现在一把年纪了还在刷题。 过去的都过去了,接下来好好努力吧。

三刷:

这次就比较熟练了,尝试一些不同的编程风格。  4/4/2016。

Java:

Time Complexity - O(n), Space Complexity - O(1)。

public class Solution {
    public int[] singleNumber(int[] nums) {
        int[] res = new int[2];
        if (nums == null || nums.length < 2) return res;
        int a_xor_b = 0;
        for (int num : nums) { a_xor_b ^= num; }
        int diffIndex = 0;
        while (diffIndex < 32) {
            if (((a_xor_b >> diffIndex) & 1) == 1) { break; }
            diffIndex++;
        }
        int num1 = 0;
        for (int num : nums) {
            if (((num >> diffIndex) & 1) == 1) { num1 ^= num; }
        }
        res[0] = num1;
        res[1] = a_xor_b ^ num1;
        return res;
    }
}

Update:

public class Solution {
    public int[] singleNumber(int[] nums) {
        if (nums == null || nums.length < 2) return new int[] {-1, -1};
        int a_XOR_b = 0;
        for (int num : nums) a_XOR_b ^= num;
        int k = 0;
        while (k < 31) {
            if (((a_XOR_b >> k) & 1) == 1) break;
            k++;
        }
        int a = 0;
        for (int num : nums) {
            if (((num >> k) & 1) == 1) a ^= num;
        }
        return new int[] {a, a ^ a_XOR_b};
    }
}

Reference:

https://groups.google.com/forum/#!topic/pongba/9KCA7b484OE

https://groups.google.com/forum/#!topic/pongba/drV6dytcoJE

http://www.matrix67.com/blog/archives/511

原文地址:https://www.cnblogs.com/yrbbest/p/5018208.html