260. Single Number III (位运算)

16 篇文章 0 订阅
7 篇文章 0 订阅
LeetCode-260.Single Number III

Description

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.

Example

Input:  [1,2,1,3,2,5]
Output: [3,5]

Note

  1. The order of the result is not important.

  2. linear runtime complexity. only constant space complexity

Solution

   之前做过这个 Single Number 系列的前两个版本: LeetCode- 137.Single Number II (位运算), 并提供了使用位运算的解法.

   与之前解法不同, 该题 Single Number III 中最终的解不止一个, 而是有两个不同的解。

   首先想到的应该与前两个系列的题一样的思路, 使用运算符 ^, & 用 x1, x2… 等来保存每个数出现的次数等思想。 但是该题最终有两个结果, 如 Example 中的 3, 5, 这样, 直接使用异或操作 x ^= nums[i] 之后, 最终 x 中存的是 35 两个数的异或结果。

   参考别人的思路, 这里要想办法将所有数划分为两类, 一类包含 3, 另一类包含 5, 并且相同数将在同一类中。 使用 a^ 第一类, 使用 b^ 第二类, 最终得到的结果中, a 就是第一个要求的结果, b 就是第二个要求的结果。 返回 a, b 就是最终要求的两个数。

   具体的划分规则, 这里采用的是利用 x倒数第一个 1 来划分(注意 x 是所有数 ^ 的结果)。 利用位运算 (x & (x-1)) ^ x 即可得到 x 的最后一个 1, 使用变量 lastbit 记录。 其中重要的一条是: x最后一个 1 只能是由 35 其中的一个数提供, 要么是 3, 要么是 5 (异或操作)。

3 : "011",  5 : "101"   3 ^ 5 : "110"
=> lastbit: "010", 只有一个 1, 并且由 3 提供

   最终, 再次遍历所有元素, 将每个元素 elelastbit 进行 & 运算, 根据 & 运算结果将所有数划分为两类, 分别进行 ^ 运算。

Code

class Solution {
public:
    vector<int> singleNumber(vector<int>& nums) {
        int x = 0, y;
        vector<int> retvec;
        for(int ele : nums) x ^= ele;
        
        // 取 x 的最后一位
        int lastbit = (x & (x - 1)) ^ x;
        
        // lastbit 只可能由最后结果 a, b 中的一个提供
        // 因此, 以 lastbit 为依据, 将 a, b 划分到不同组, 
        // 并且同组中出现过两次数的都将变为零
        
        int a = 0, b = 0;
        for(int ele : nums) {
            if(ele & lastbit) a ^= ele;
            else b ^= ele;
        }
        
        return vector<int>{a, b};
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值