力扣刷题笔记 → 260. 只出现一次的数字 III

204 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

题目

给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。你可以按 任意顺序 返回答案。

进阶:你的算法应该具有线性时间复杂度。你能否仅使用常数空间复杂度来实现?

示例

输入: nums = [1,2,1,3,2,5]
输出: [3,5]
解释: [5, 3] 也是有效的答案。

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

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

提示

  • 2 <= nums.length <= 3 * 10^4
  • -2^31 <= nums[i] <= 2^31 - 1
  • 除两个只出现一次的整数外,nums 中的其他数字都出现两次

解题思路

哈希表

最简单的方法就是通过哈希表来进行排除,将所有出现两次的数字删除,保留仅剩的两个只出现一次的整数。

class Solution {
    public int[] singleNumber(int[] nums) {
        Set<Integer> set = new HashSet<>();
        // 遍历数组
        for(int num : nums){
            // 判断是否已出现过该数值
            if(set.contains(num)){
                // 删除重复数值
                set.remove(num);
            }else{
                // 数值登记
                set.add(num);
            }
        }

        // 得到剩余的两个数值
        int[] result = new int[2];
        int idx = 0;
        for(int num : set){
            result[idx++] = num;
        }

        // 返回结果
        return result;
    }
}

 复杂度分析

  •   时间复杂度:O(N)O(N)
  •   空间复杂度:O(N)O(N)

位运算

这道题位【136.只出现一次的数字】的进阶版本,在136这道题中,我们可以利用异或运算的特性,仅需遍历一遍数组即可求得唯一一个数字。

对于这道题,数组中其余元素依旧是只出现了2次,不同的地方在于该题有两个元素只出现了一次,如果还是按照136的解法来统计的话,最终的结果将会是a \bigoplus b, 我们还得将该结果进行拆分,得到对应的两个数值。

  1. 首先可以肯定一点的是统计结果不等于0, 如果结果为0的话,代表a == b,与题目有冲突。
  2. 既然a != b,那么我们就可以通过公式 x & -x 来求得二进制中最低为的1,用以区分a, b
  3. 将数组中所有元素以 x & -x 的结果来分类,并去除重复元素,求得最终结果。

GIF 2021-10-29 18-11-43.gif

class Solution {
    public int[] singleNumber(int[] nums) {
        int sum = 0;
        // 得到 a ^ b
        for(int num : nums){
            sum ^= num;
        }

        // 求得最低位的1
        sum &= -sum;

        int num1 = 0, num2 = 0;
        for(int num : nums){
            // 区分num1与num2
            if((num & sum) != 0){
                num1 ^= num;
            }else{
                num2 ^= num;
            }
        }
        
        // 返回结果
        return new int[]{num1, num2};
    }
}

 复杂度分析

  •   时间复杂度:O(N)O(N)
  •   空间复杂度:O(1)O(1)

最后

文章有写的不好的地方,请大佬们不吝赐教,错误是最能让人成长的,愿我与大佬间的距离逐渐缩短!

如果觉得文章对你有帮助,请 点赞、收藏、关注、评论 一键四连支持,你的支持就是我创作最大的动力!!!

题目出处: leetcode-cn.com/problems/si…