​LeetCode刷题实战260:只出现一次的数字 III

算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试。所以,为了提高大家的算法能力,这个公众号后续每天带大家做一道算法题,题目就从LeetCode上面选 !

今天和大家聊的问题叫做 只出现一次的数字 III,我们先来看题面:

https://leetcode-cn.com/problems/single-number-iii/

Given an integer array 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. You can return the answer in any order.

Follow up: Your algorithm should run in linear runtime complexity. Could you implement it using only constant space complexity?

给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。找出只出现一次的那两个元素。你可以按 任意顺序 返回答案。

进阶:你的算法应该具有线性时间复杂度。你能否仅使用常数空间复杂度来实现?

示例

示例 1:

输入:nums = [1,2,1,3,2,5]
输出:[3,5]
解释:[5, 3] 也是有效的答案。

示例 2:

输入:nums = [-1,0]
输出:[-1,0]

示例 3:

输入:nums = [0,1]
输出:[1,0]

解题

我们知道两个相同的数异或之后就为0,所以对于nums数组中的所有数,异或之后的结果就是那两个只出现一次的数异或的值。

这个值必然不为0(因为这两个数是不同的),所以这个数的二进制表示里,从低位往高位必然有一位1,这一位是1,说明这两个数在这一位的二进制表示不同(因为这个数是异或得到的),我们可以以与这一位的1与的结果为1还是为0,把nums数组的元素分为两组,则这两个不同的数必然被分在不同的组。又由于相同的数异或为0,所以同一组的数全部进行异或操作,最后两组剩下的值就分别是这两个不同的数了。

class Solution {
public:
    vector<int> singleNumber(vector<int>& nums) {
        vector<int> res(2, 0); // 分为两组
        int sum = 0; // sum是nums所有元素异或的结果
        for(int i = 0; i < nums.size(); ++i) {
            sum ^= nums[i];
        }
        int firstOne = sum & (-sum); // 得到最低位的1,sum & (-sum)这是一个常见的技巧
        for(int i = 0; i < nums.size(); ++i) {
            if(firstOne & nums[i]) { // 如果和firstOne相与为1,分到第一组(并且第一组所有元素进行异或操作)
                res[0] ^= nums[i];
            } else { // 否则到第二组(并且第二组所有元素进行异或操作)
                res[1] ^= nums[i];
            }
        }
        return res;
    }
};

好了,今天的文章就到这里,如果觉得有所收获,请顺手点个在看或者转发吧,你们的支持是我最大的动力 。

上期推文:

LeetCode1-240题汇总,希望对你有点帮助!

LeetCode刷题实战241:为运算表达式设计优先级

LeetCode刷题实战242:有效的字母异位词

LeetCode刷题实战243:最短单词距离

LeetCode刷题实战244:最短单词距离 II

LeetCode刷题实战245:最短单词距离 III

LeetCode刷题实战246:中心对称数

LeetCode刷题实战247:中心对称数II

LeetCode刷题实战248:中心对称数III

LeetCode刷题实战249:移位字符串分组

LeetCode刷题实战250:统计同值子树

LeetCode刷题实战251:展开二维向量

LeetCode刷题实战252:会议室

LeetCode刷题实战253:会议室II

LeetCode刷题实战254:因子的组合

LeetCode刷题实战255:验证前序遍历序列二叉搜索树

LeetCode刷题实战256:粉刷房子

LeetCode刷题实战257:二叉树的所有路径

LeetCode刷题实战258:各位相加

LeetCode刷题实战259:较小的三数之和

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员小猿666

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值