[LeetCode] (medium) 260. Single Number III Medium

博客围绕LeetCode上一道题展开,题目是在数组中找出仅出现一次的两个元素,其他元素均出现两次。提到一路异或得到两目标数纠缠状态,重点是分离。还参考了相关文章,将原数组划分为两个子数组来求解,同时提到取mask时类似树状数组的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

https://leetcode.com/problems/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.

Example:

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

Note:

  1. The order of the result is not important. So in the above example, [5, 3] is also correct.
  2. Your algorithm should run in linear runtime complexity. Could you implement it using only constant space complexity?

一路异或之后可以得到两个目标数纠缠在一起的状态,重点在于分离

一开始设想再以这个纠缠状态为起点一路异或一遍,当某个数使他为零时,就找到了第一个目标数,但是显然这个方法是错的

参考了 https://segmentfault.com/a/1190000004886431 

直观上理解就是一种将原数组的划分,分为两个子数组,每个数组中满足“有一个数出现一次,剩下的数出现两次”这一特性,就容易解了

注意取mask的时候类似于树状数组 -n = ~n+1 = ~(n-1)(证明思路:先证带符号数加法与无符号数相同,再证 n+~n+1 = 0,再证~n+1 = ~(n-1),利用10...0后缀)

class Solution {
public:
    vector<int> singleNumber(vector<int>& nums) {
        vector<int> result(2);
        
        int combine = 0;
        for(int cur : nums){
            combine ^= cur;
        }
        
        int mask = combine & (~(combine-1));
        
        int a = 0, b = 0;
        for(int cur : nums){
            if(cur & mask){
                a ^= cur;
            }else{
                b ^= cur;
            }
        }
        result[0] = a;
        result[1] = b;
        return result;
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值