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的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode只出现一次的数字i/ii/iii

[LeetCode] 136. 只出现一次的数字

[LeetCode] 136. 只出现一次的数字

leetcode 简单第三十三题 只出现一次的数字

Leetcode No.137 只出现一次的数字 II

LeetCode 136. 只出现一次的数字