Leetcode--Single Number III

来源:互联网 发布:新闻资讯源码 作家 编辑:程序博客网 时间:2024/06/09 16:48

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?

解题思路

哦豁又是一道很水的位运算的题目。由于要求使用O(n)的时间和空间复杂度,所以在这里使用位运算的小技巧,求得在数列中只出现一次的两个数。
基本的原理就是 在二进制数制中,A 异或 B 的结果中保留A与B不同的位数为1,而任意数异或自己的结果都是0,因此我们可以概括为以下步骤:
1.求得所有数依次异或的结果,在数列中出现两次的数,由于一定会异或到自身,所以他们对结果没有影响,最后整个数列异或的结果是在数列中只出现一次的两个数异或的结果,也即 在题目的例子中 3 ^ 5 = [110]
2.现在已知两个数异或彼此的结果,要倒推回这两个数。又因为这两个数彼此之间互不相同,在二进制数制中他们一定有一位不同,我们取异或结果的二进制位数中最低为1的一位其他位置0,也即对于[110]我们取[010].然后我们用得到的这个数去和数组中的数相互异或,将他们分成两个组。
3.由于出现两次的那些数一定会出现在相同的组内,将这两个组内的元素依次异或,最后得到的结果一定就是我们要求的那两个数。

程序代码

class Solution {public:    vector<int> singleNumber(vector<int>& nums) {        vector<int> result(2, 0);         int exclusive = nums[0];         for(int i = 1; i < nums.size(); i++) {            exclusive = exclusive ^ nums[i];         }        exclusive = exclusive & (-exclusive);         for(int i = 0; i < nums.size(); i++) {            if((nums[i] & exclusive) != 0) {                result[0] = result[0] ^ nums[i];             }            else {                result[1] = result[1] ^ nums[i];             }        }        return result;     }}; 
0 0
原创粉丝点击