1. 程式人生 > >LintCode 1112: Set Mismatch (XOR經典題)

LintCode 1112: Set Mismatch (XOR經典題)

  1. Set Mismatch
    The set S originally contains numbers from 1 to n. But unfortunately, due to the data error, one of the numbers in the set got duplicated to another number in the set, which results in repetition of one number and loss of another number.

Given an array nums representing the data status of this set after the error. Your task is to firstly find the number occurs twice and then find the number that is missing. Return them in the form of an array.

Example
Input: nums = [1,2,2,4]
Output: [2,3]
Notice
1.The given array size will in the range [2, 10000].
2.The given array’s numbers won’t have any order.

我的思路是:
先排序,然後找出nums[i-1]=nums[i],則num[i]就是nums[]裡面出錯的那個,設其為candidate_err。
那怎麼找到[1…n]裡面出錯的那個呢?假設其為candidiate_orig。
用xor就可以了。
假設nums = [3,2,3,4,6,5],排序後為[2,3,3,4,5,6]。
可得candidate_err = 3。
然後XOR所有的nums,再XOR所有的1…n,再XOR candidate_err。最後結果就是candidate_orig = 1。
即 2 ^ 3 ^ 3 ^ 4 ^ 5 ^ 6 ^ 1 ^ 2 ^ 3 ^ 4 ^ 5 ^ 6 ^ 3

= 1.
最後還異或3是為了確保3有偶數個,這樣3的異或結果就為0了。

程式碼如下:

class Solution {
public:
    /**
     * @param nums: an array
     * @return: the number occurs twice and the number that is missing
     */
    vector<int> findErrorNums(vector<int> &nums) {
        int len = nums.size();
        if (len == 0) return vector<int>(2, 0);
        
        sort(nums.begin(), nums.end());
        int candidate_orig = 0, candidate_err = 0;
        for (int i = 1; i <= len; ++i) {
            if (nums[i - 1] == nums[i]) {
                candidate_err = nums[i];
                break;
            }
        }
        int xor_result = 0;
        for (int i = 1; i <= len; ++i) {
            xor_result ^= i;
            xor_result ^= nums[i - 1];
        }
        xor_result ^= candidate_err;
        
        candidate_orig = xor_result;
        
        return vector<int>{candidate_err, candidate_orig};
    }
};