算法题分享 | 只出现一次的数字 II

25 阅读2分钟

此去经年,眉目成书🌋_11_蘅皋暮_来自小红书网页版.jpg

题目

给你一个整数数组 nums ,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次 。 请你找出并返回那个只出现了一次的元素。

你必须设计并实现线性时间复杂度的算法且使用常数级空间来解决此问题。

示例 1:

输入: nums = [2,2,3,2]
输出: 3

示例 2:

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

 

提示:

  • 1 <= nums.length <= 3 * 10⁴
  • -2³¹ <= nums[i] <= 2³¹ - 1
  • nums 中,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次

题解

解题思路

本题可以直接遍历一遍数组,利用哈希表把各个数出现的次数记录下,最终即可知道哪个数只出现了一次,这种方法虽然简单,但是空间复杂度不是常量级的。接下来着重介绍另一种方法。

由于其余数都是恰出现 3 次,所以除答案以外所有数的第 i (任意)位二进制位值之和都会是 3 的倍数(包括 0,也算是 3 的倍数)。再进一步,对于第 i 位二进制位,我们只需要把包含答案在内所有数的第 i 位求和,再对 3 求余,只要余数不为 0,即表示答案的第 i 位为 1。

由于题目中说明了 -2³¹ <= nums[i] <= 2³¹ - 1,一共有 32 位,只需要使用以上的方法逐一得到各位的值,也就得到答案了。

代码

class Solution {
    public int singleNumber(int[] nums) {
        
        int ans = 0;

        for (int i = 0; i < 32; i++) {
            
            int sum = 0;

            for (int num : nums) {    
                // 获取到第 i 位二进制数字
                sum += (num >> i) & 1;
            }

            // 对 3 求余不等于 0,就说明答案的第 i 位二进制为 1 
            if (sum % 3 != 0) {
                ans |= 1 << i;
            }
            
        }

        return ans;
    }
}

复杂度分析

  • 时间复杂度:O(nlogC)
    其中 n 位数组的长度, C 为元素的数据范围,例如本题中范围为 2³²,则 log 2³² = 32。
  • 空间复杂度:O(1)

优质项目推荐

推荐一个可用于练手、毕业设计参考、增加简历亮点的项目。

lemon-puls/txing-oj-backend: Txing 在线编程学习平台,集在线做题、编程竞赛、即时通讯、文章创作、视频教程、技术论坛为一体

公众号

有兴趣可以关注公众号一起学习更多的干货哈!

扫码_搜索联合传播样式-白色版.png