LeetCode 0137. 只出现一次的数字 II
Posted Tisfy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 0137. 只出现一次的数字 II相关的知识,希望对你有一定的参考价值。
【LetMeFly】137.只出现一次的数字 II
力扣题目链接:https://leetcode.cn/problems/single-number-ii/
给你一个整数数组 nums
,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次 。请你找出并返回那个只出现了一次的元素。
示例 1:
输入:nums = [2,2,3,2] 输出:3
示例 2:
输入:nums = [0,1,0,1,0,1,99] 输出:99
提示:
1 <= nums.length <= 3 * 104
-231 <= nums[i] <= 231 - 1
nums
中,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次
进阶:你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
方法一:哈希表
这道题使用哈希表最简单,只是复杂度不符合进阶要求。
对于C++
,直接使用unordered_map
统计一下每个数字出现的次数,然后遍历一遍哈希表,返回只出现了一次的数字即可。
- 时间复杂度 O ( n ) O(n) O(n),其中 n n n是数组中数字的个数
- 空间复杂度 O ( n ) O(n) O(n),不符合本题进阶的 O ( 1 ) O(1) O(1)要求
AC代码
C++
class Solution
public:
int singleNumber(vector<int>& nums)
unordered_map<int, int> ma;
for (int& t : nums)
ma[t]++;
for (auto& [num, times] : ma)
if (times == 1)
return num;
return -1; // FAKE_RETURN
;
方法二:位运算
稍微多想一想,这道题可以使用位运算来解决。
一个 i n t int int类型的数字有 32 32 32位,对于其中的某一位:
遍历所有的数字,并统计这一位出现的次数。
出现了 3 3 3次的数字,对这一位的出现次数的贡献要么是 3 3 3,要么是 0 0 0。总之都是 3 3 3的倍数。
如果只出现了一次的数字的这一位是 1 1 1,那么这一位出现的总次数就是 3 的倍数 + 1 3的倍数+1 3的倍数+1;
如果只出现了一次的数字的这一位是 0 0 0,那么这一位出现的总次数就是 3 的倍数 3的倍数 3的倍数。
因此,对于某一位,如果出现次数不是 3 3 3的倍数,就让答案的这一位为 1 1 1,最终即能得到只出现了一次的数字
- 时间复杂度 O ( n log C ) O(n\\log C) O(nlogC),其中 n n n是数组中数字的个数, C C C是一个数字的范围( 2 32 2^32 232)。因此 log C \\log C logC就是 32 32 32
- 空间复杂度 O ( 1 ) O(1) O(1),符合本题进阶的 O ( 1 ) O(1) O(1)要求
AC代码
C++
class Solution
public:
int singleNumber(vector<int>& nums)
int ans = 0;
for (int i = 0; i < 32; i++)
int times = 0;
for (int& t : nums)
times += (t >> i) & 1;
if (times % 3)
ans |= (1 << i);
return ans;
;
其实还有方法三:数字电路设计。太妙了,感兴趣了可参考官方题解
class Solution
public:
int singleNumber(vector<int>& nums)
int a = 0, b = 0;
for (int num: nums)
b = ~a & (b ^ num);
a = ~b & (a ^ num);
return b;
;
同步发文于CSDN,原创不易,转载请附上原文链接哦~
Tisfy:https://letmefly.blog.csdn.net/article/details/125991647
以上是关于LeetCode 0137. 只出现一次的数字 II的主要内容,如果未能解决你的问题,请参考以下文章