[LintCode/LeetCode] Single Number I & II [位运算]

391 查看

Single Number I

Problem

Given 2*n + 1 numbers, every numbers occurs twice except one, find it.

Example

Given [1,2,2,1,3,4,3], return 4

Challenge

One-pass, constant extra space.

Note

只要循环异或,出现两次的都变成0了,最后只剩下出现一次的single number。但要注意,要分析A为空或为null的情况,返回0.

Solution

public class Solution {
    public int singleNumber(int[] A) {
        if (A == null || A.length == 0) return 0;
        int n = 0;
        for (int num: A) {
            n ^= num;
        }
        return n;
    }
}  

HashSet

public class Solution {
    public int singleNumber(int[] A) {
        if (A == null || A.length == 0) return 0;
        Set<Integer> set = new HashSet();
        int res = 0;
        for (int a: A) {
            if (set.contains(a)) set.remove(a);
            else set.add(a);
        }
        res = set.iterator().next();
        return res;
    }
}

Single Number II

Problem

Given 3*n + 1 numbers, every numbers occurs triple times except one, find it.

Example

Given [1,1,2,3,3,3,2,2,4,1] return 4

Challenge

One-pass, constant extra space.

Note

假设数a第一次出现,只存在ones里,第二次出现,从ones里消去,然后存在twos里,第三次出现,由于ones不存取已经在twos里的数,就只从twos里消去。整个过程相当于,直接在ones和twos里去掉既是ones又是twos的threes。所以最后返回的ones,一定是只出现过一次的single number,而出现两次的都在twos里,出现三次的都被消去了。

Solution

public class Solution {
    public int singleNumberII(int[] A) {
        int ones = 0, twos = 0;
        for (int a: A) {
            ones = ones^a & ~twos;
            twos = twos^a & ~ones;
        }
        return ones;
    }
}