您现在的位置是:首页 >技术交流 >( 位运算 ) 260. 只出现一次的数字 III ——【Leetcode每日一题】网站首页技术交流

( 位运算 ) 260. 只出现一次的数字 III ——【Leetcode每日一题】

酷酷的懒虫 2024-06-14 17:20:26
简介( 位运算 ) 260. 只出现一次的数字 III ——【Leetcode每日一题】

❓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 < = n u m s . l e n g t h < = 3 ∗ 1 0 4 2 <= nums.length <= 3 * 10^4 2<=nums.length<=3104
  • − 2 31 < = n u m s [ i ] < = 2 31 − 1 -2^{31} <= nums[i] <= 2^{31} - 1 231<=nums[i]<=2311
  • 除两个只出现一次的整数外,nums 中的其他数字都出现两次

?思路:异或

算法要求时间复杂度是 O ( N ) O(N) O(N),时间复杂度是 O ( 1 ) O(1) O(1) 所以不可以通过暴力解法来解决该题,就考虑是否可以通过位运算求解!

基础知识必知位运算基本原理

对数组中的数字进行 异或 运算,那么最后的结果一定是只出现一次的两个数字的异或运算结果

假设只出现一次的两个数是 xy 那么最后的结果是x ^ y

  1. 因为xy 是不相同的,所以他们肯定在二进制有不同的1值;
  2. 可以使用 (x ^ y) & (- x ^ y)得到 最低的那一位 1:
    • 根据该位置是否为 1,将数组中的数字分成两组;
    • 对这两组分别做异或运算,就可得到只出现一次的两个值!

?代码:(Java、C++)

Java

class Solution {
    public int[] singleNumber(int[] nums) {
        int diff = 0;
        for(int num : nums) diff ^= num;
        // 防止溢出
        diff = (diff == Integer.MIN_VALUE) ? 1 : diff & (-diff);//得到最低那一位1
        int[] ans = new int[2];
        for(int num : nums){
            if((num & diff) == diff){
                ans[0] ^= num;
            }else{
                ans[1] ^= num;
            }
        }
        return ans;
    }
}

C++

class Solution {
public:
    vector<int> singleNumber(vector<int>& nums) {
        int diff = 0;
        for(int num : nums) diff ^= num;
        // 防止溢出
        diff = (diff == INT_MIN) ? 1 : diff & (-diff);//得到最低那一位1
        vector<int> ans(2);
        for(int num : nums){
            if((num & diff) == diff){
                ans[0] ^= num;
            }else{
                ans[1] ^= num;
            }
        }
        return ans;
    }
};

? 运行结果:

在这里插入图片描述

? 复杂度分析:

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

题目来源:力扣。

放弃一件事很容易,每天能坚持一件事一定很酷,一起每日一题吧!
关注我 leetCode专栏,每日更新!

注: 如有不足,欢迎指正!

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。