【LeetCode从零单刷】Single Number III

本文介绍了一种高效算法,用于在一个数组中找到仅出现一次的两个数,其余元素均出现两次。通过异或操作和位运算技巧,实现算法在常数空间复杂度下运行。

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

题目:

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?

解答:

如果只有一个落单的数,是不是很好处理?因为相同的数位异或之后答案是0,每个数都进行异或操作之后,是不是就剩下那个单一的数。

 那么,如果我将这一题,分为两个组,每个部分仅包含一个落单的数,其他都是成双成对出现的话,是不是就可以了。

如何区分呢?首先,我们将每个数进行异或操作,得到一个答案 tmp,本质就是那两个落单的数异或后的结果

这里利用一个位运算技巧:如果两个数的异或结果为tmp,则 tmp&(~(tmp - 1)) 的结果就是这两个数最低不相同的那一位。依靠与这一位相与,可以将这两个数区分开来。

对于这两个数之外的其他数呢?相与的结果无所谓,只要保证他们成对出现即可,两个相同的数与这一位相与之后的结果肯定是相同的,必然会分到同一组。

class Solution {
public:
    vector<int> singleNumber(vector<int>& nums) {
        int len = nums.size();
        
        int tmp = 0;
        for(int i = 0; i < len; i++)
        {
            tmp = tmp ^ nums[i];
        }
        int lastbit = tmp & (~(tmp - 1));
        int ansA = 0, ansB = 0;
        for(int i = 0; i < len; i++)
        {
            if(nums[i] & lastbit)
            {
                ansA ^= nums[i];
            }
            else{
                ansB ^= nums[i];
            }
        }
        vector<int> ans = {ansA, ansB};
        return ans;
    }
};

这里有一个小编程技巧,利用花括号将某些确定的数组成一个vector:vector<int> ans = {ansA, ansB};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值