260. 只出现一次的数字 III【我亦无他唯手熟尔】

简介: 260. 只出现一次的数字 III【我亦无他唯手熟尔】

260. 只出现一次的数字 III

260. 只出现一次的数字 III
给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。你可以按 任意顺序 返回答案。
进阶:你的算法应该具有线性时间复杂度。你能否仅使用常数空间复杂度来实现?
示例 1:
输入:nums = [1,2,1,3,2,5]
输出:[3,5]
解释:[5, 3] 也是有效的答案。
示例 2:
输入:nums = [-1,0]
输出:[-1,0]
示例 3:
输入:nums = [0,1]
输出:[1,0]
提示:
2 <= nums.length <= 3 * 104
-231 <= nums[i] <= 231 - 1
除两个只出现一次的整数外,nums 中的其他数字都出现两次

题解

思路
暴力解法
class Solution {
    public int[] singleNumber(int[] nums) {
        int [] result=new int [2];
        int n=nums.length;
        int k=0;
        for(int i=0;i<n;i++){
            int showup=0;
            for(int j=0;j<n;j++){
                if(i==j){
                    continue;
                }else{
                    if(nums[i]==nums[j]){
                        showup=1;
                        break;
                    }
                }
            }
            if(showup==0){
                result[k]=nums[i];
                k++;
            }
        }
        return result;
    }
}



官方

在理解如何使用位运算解决本题前,读者需要首先掌握「136. 只出现一次的数字」中的位运算做法。

136. 只出现一次的数字【我亦无他唯手熟尔】
假设数组 nums 中只出现一次的元素分别是 x1 和 x2 。如果把 nums 中的所有元素全部异或起来,得到结果 x,那么一定有:

x = x1 ⊕ x2


其中 ⊕ 表示异或运算。这是因为 nums 中出现两次的元素都会因为异或运算的性质 a⊕b⊕b=a 抵消掉,那么最终的结果就只剩下x1和x2 的异或和。


x 显然不会等于 0,因为如果x=0,那么说明 x1 = x2


这样 x1 和 x2就不是只出现一次的数字了。

因此,我们可以使用位运算 x & -x 取出 x 的二进制表示中最低位那个 1,设其为第 l位,那么 x1 ⊕和x2中的某一个数的二进制表示的第 l位为 0,另一个数的二进制表示的第 l 位为 1。在这种情况下, x1 ⊕ x2的二进制表示的第 l位才能为 1。


这样一来,我们就可以把nums 中的所有元素分成两类,其中一类包含所有二进制表示的第 l 位为 0 的数,另一类包含所有二进制表示的第 l 位为 1 的数。可以发现:


对于任意一个在数组nums 中出现两次的元素,该元素的两次出现会被包含在同一类中;


对于任意一个在数组 nums 中只出现了一次的元素,即 x1 和 x2,它们会被包含在不同类中。


因此,如果我们将每一类的元素全部异或起来,那么其中一类会得到 x1 ,另一类会得到 x2 。这样我们就找出了这两个只出现一次的元素。


作者:LeetCode-Solution

链接:https://leetcode-cn.com/problems/single-number-iii/solution/zhi-chu-xian-yi-ci-de-shu-zi-iii-by-leet-4i8e/

来源:力扣(LeetCode)

class Solution {
    public int[] singleNumber(int[] nums) {
        int xorsum = 0;
        for (int num : nums) {
            xorsum ^= num;
        }
        // 防止溢出
        int lsb = (xorsum == Integer.MIN_VALUE ? xorsum : xorsum & (-xorsum));
        int type1 = 0, type2 = 0;
        for (int num : nums) {
            if ((num & lsb) != 0) {
                type1 ^= num;
            } else {
                type2 ^= num;
            }
        }
        return new int[]{type1, type2};
    }
}

复杂度分析

  • 时间复杂度:O(n),其中 n 是数组 nums 的长度。
  • 空间复杂度:O(1)。

相关文章
1446. 连续字符【我亦无他唯手熟尔】
1446. 连续字符【我亦无他唯手熟尔】
55 0
598. 范围求和 II【我亦无他唯手熟尔】
598. 范围求和 II【我亦无他唯手熟尔】
67 0
500. 键盘行【我亦无他唯手熟尔】
500. 键盘行【我亦无他唯手熟尔】
97 0
496. 下一个更大元素 I【我亦无他唯手熟尔】
496. 下一个更大元素 I【我亦无他唯手熟尔】
49 0
|
算法
268. 丢失的数字【我亦无他唯手熟尔】
268. 丢失的数字【我亦无他唯手熟尔】
57 0
|
算法
136 137 260只出现一次的数字【我亦无他唯手熟尔】
136 137 260只出现一次的数字【我亦无他唯手熟尔】
82 0
400. 第 N 位数字【我亦无他唯手熟尔】
400. 第 N 位数字【我亦无他唯手熟尔】
76 0
136. 只出现一次的数字【我亦无他唯手熟尔】
136. 只出现一次的数字【我亦无他唯手熟尔】
66 0
367. 有效的完全平方数【我亦无他唯手熟尔】
367. 有效的完全平方数【我亦无他唯手熟尔】
63 0
299. 猜数字游戏【我亦无他唯手熟尔】
299. 猜数字游戏【我亦无他唯手熟尔】
62 0

热门文章

最新文章