首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【Leetcode】137.只出现一次的数字(逻辑运算推导)

【Leetcode】137.只出现一次的数字(逻辑运算推导)

作者头像
FishWang
发布2025-08-27 13:12:21
发布2025-08-27 13:12:21
1360
举报

题目链接

点击打开链接

题目描述

在这里插入图片描述
在这里插入图片描述

解题思路

首先我们分析一下题意,一个数组中只有一个数出现了1次,其余的数都出现了3次。并且要求

O(n)

的时间复杂度和

O(1)

的空间复杂度。也就是不能用线性表、HashSet、HashMap这些数据结构了。

解法一

这题还是从二进制位来考虑,分以下2种情况:

  1. 如果这个二进制位出现了3n次1(3次、6次、9次等),那么就说明结果在这个二进制位上不为1。
  2. 如果这个二进制位出现了3n+1次1(1次、4次、7次等),那么就说明结果在这个二进制位上为1。

需要注意,一个二进制位上不可能出现3n+2次1,所以只会有上面两种情况。

那么第一种解法就有了:统计每个二进制位上1出现的次数,如果是3n次,则这个位为0;如果是3n+1次,则这个位为1。

代码如下:

代码语言:javascript
复制
class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int ans = 0;
        for (int j=0; j<32; j++)  // int的32个二进制位
        {
            int cnt = 0;
            for (int i=0; i<nums.size(); i++)
            {
                if (nums[i] & (1 << j))  // 判断这个位是不是1
                    cnt++;
            }
            if (cnt % 3 == 1)
                ans = ans | (1 << j);
        }
        return ans;
    }
};
解法二

第一种解法思路上很清楚,但是如果数字的范围比较大的话,就不只是扫描32个二进制位了,时间复杂度要更高点了。

所以再考虑一种可以更高效对每个二进制位计数的方法。一个整数的每个二进制位的表示只能是0或1两种,只能表示2种状态,但是两个数共同来控制就可以了。我们引出两个变量ab,接下来我们只考虑这个两个变量的一个二进制位,也就是只有0和1两种状态。变量c是读入的数,列出真值表如下:

a

b

c

结果a

结果b

0

0

0

0

0

0

1

0

0

1

1

0

0

1

0

-

-

-

-

-

0

0

1

0

1

0

1

1

1

0

1

0

1

0

0

来说明一下上表的涵义。

  • 前两列表示当前的a、b值。
  • 第三列表示输入的数字c。
  • 后两列表示当前的a、b状态遇到输入c后,会变成什么状态。

然后按输入c分两部分看(表中已经隔开):

  1. 输入c为0,那么表示这个二进制位没有计数,a和b保持之前的状态。
  2. 输入c为1,a和b要进行相应的进位来计数,如果ab已经是10了,表示这个数字已经计数2次了,第3次要清零,变成了00

真值表理解了以后,就可以推导逻辑代数式啦(不会的可以参考这里)(还可以进一步化简):

\begin{matrix} \\a = a\bar{b}\bar{c}+\bar{a}bc \\b=\bar{a}b\bar{c}+\bar{a}\bar{b}c=\bar{a}·(b\bar{c}+\bar{b}c)=\bar{a}·(b\bigoplus c) \end{matrix}

最后b就是结果啦,因为b的二进制位上为1时表示这个数字出现了1次。

代码如下:

代码语言:javascript
复制
class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int a = 0;
        int b = 0;
        for (int i=0; i<nums.size(); i++)
        {
            int ta = a;
            a = (a & (~b) & (~nums[i])) | (~a & b & nums[i]);
            b = ~ta & (b ^ nums[i]);
        }
        return b;
    }
};
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-08-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 题目链接
  • 题目描述
  • 解题思路
    • 解法一
    • 解法二
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档