剑指offer 62. 数组中唯一只出现一次的数字

✍个人博客:https://blog.csdn.net/Newin2020?spm=1011.2415.3001.5343
📚专栏地址:剑指offer系列题解
📝原题地址:题目地址
📣专栏定位:为找工作的小伙伴整理常考算法题解,祝大家都能成功上岸!
❤️如果有收获的话,欢迎点赞👍收藏📁,您的支持就是我创作的最大动力💪

题目描述

在一个数组中除了一个数字只出现一次之外,其他数字都出现了三次。

请找出那个只出现一次的数字。

你可以假设满足条件的数字一定存在。

思考题:

  • 如果要求只使用 O(n) 的时间和额外 O(1) 的空间,该怎么做呢?
数据范围

数组长度 [1,1500]。

样例
输入:[1,1,1,2,2,2,3,4,4,4]

输出:3

方法一:状态机 O(n)

这道题是要找到只出现一次的那个数字,我们可以用位运算的思想,将数字用二进制表示拆分成 32 位(因为数据范围内数值最大也不会超过 32 位),将所有数字异或之后,如果每一位上为 1 出现的次数 %3 结果为 1 则说明只出现一次的那个数字在该位上为 1 ;如果 %3 结果为 0 ,则该数该位上为 0

因为其他数字出现了三次,所以同一个位置上如果有 1 的话就会出现三次,%3 就会得 0 。如果这时只出现一次的数在该位置上出现了 1 ,则 %3 就会多出一次来,从而进行区分。

所以这道题可以用类似于状态机的思想来做,需要用到 onetwo 两个变量。按下面这个思路来,可以发现二进制位置上遇到 1 的时候按如下公式进行遇到 3 后又会得到开始的结果即循环一次周期为 3 ;而遇到 0 的话就会发生自环,即不会改变状态:

  • one = (one ^ x) & ~two
  • two = (two ^ x) & ~one

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n8dm3hoG-1665655886771)(剑指offer第二版C++题解.assets/image-20220821171124321.png)]

class Solution {
public:
    int findNumberAppearingOnce(vector<int>& nums) {
        int one = 0, two = 0;
        for (auto x : nums)
        {
            one = (one ^ x) & ~two;
            two = (two ^ x) & ~one;
        }
        return one;
    }
};

欢迎大家在评论区交流~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值