260.Single Number III

来源:互联网 发布:申请域名 编辑:程序博客网 时间:2024/06/06 19:23

题目: 
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? 
题意: 
给定一个数组,其中只有两个元素是出现一次的,其他元素都是出现两次的。找出这两个元素。 
思路: 
我们知道如果一个数组中只有一个元素是出现一次,其他元素是出现两次的解题思路。只需要把所有的元素异或之后,那么异或的结果就是那个最终的单个的元素。这个思路很简单,就是把每个数理解为对应的二进制位,那么那些出现两次的元素,他们在1出现的所有位置,1都出现两次,异或完就还是0。而对于那个单出现一次得元素,它每个二进制位对应的数字出现一次。所以最终的异或结果就相当于把出现两次的元素全部去除。 
有了上面的基本的思路,我们可以将数组分成两个部分,每个部分里只有一个元素出现一次,其余元素都出现两次。那么使用这种方法就可以找出这两个元素了。不妨假设这两个元素是x,y,而且x!=y,那么最终所有的元素异或的结果就是res = x^y.很显然,res!= 0,如果res=0,那么x=y,与题意不符。既然res!=0,那么我们可以找出其二进制表示中的某一位是1,我们从低位往高位找,找到第一个二进制位是1的位置。对于原来的数组,我们可以根据这个位置是不是1就可以将数组分成两个部分。x,y在不同的两个子数组中。而且对于其他成对出现的元素,要么在x所在的那个数组,要么在y所在的那个数组。假设不是的话,那说明这一对数在这一位上一个是0一个是1,很显然不符它们是一对相等数的条件。

以上。 
代码如下:

class Solution {public:    vector<int> singleNumber(vector<int>& nums) {        if (nums.size() < 2)return vector<int>();        else if (nums.size() == 2)return nums;        int all = 0;        for (auto num:nums)            all ^= num;        int flag = 0x01;        while (true) {            if (flag & all)break;            flag <<= 1;        }        int res1 = 0, res2 = 0;        for (auto num : nums) {            if (num & flag)                res1 ^= num;            else res2 ^= num;        }        vector<int> result;        result.push_back(res1);        result.push_back(res2);        return result;    }};
原创粉丝点击