Leetcode--Single Number III

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值