【每日一题】只出现一次的数字 III

文章目录

  • Tag
  • 题目来源
  • 题目解读
  • 解题思路
    • 方法一:位运算
  • 其他语言
    • c
    • python3
  • 写在最后

Tag

【位运算】【数组】【2023-10-16】


题目来源

260. 只出现一次的数字 III

【每日一题】只出现一次的数字 III_第1张图片

题目解读

找出数组中恰好只出现一次的连个元素,其余的所有元素均出现两次。要求算法的时间复杂度为线性的,空间复杂度为常量级别的。


解题思路

方法一:位运算

我们先对数组 nums 中的虽有元素进行一次异或操作,得到的值 x 是数组中仅仅出现过一次的两个数的异或值,即 x = x 1 ⨁ x 2 x = x_1 \bigoplus x_2 x=x1x2 x 1 x_1 x1 x 2 x_2 x2 分别表示数组中仅仅出现过一次的两个数。

显然,这个 x x x 的值不会等于 0,因为一旦等于 0,那么说明 x 1 = x 2 x_1 = x_2 x1=x2,这样 x 1 x_1 x1 x 2 x_2 x2 就不是仅出现一次的数了。

现在使用位运算 KaTeX parse error: Expected 'EOF', got '&' at position 3: x &̲ -x 可以得到 x x x 的二进制表示位中最低位的 1,设其为第 i,也就表示 x 1 x_1 x1 x 2 x_2 x2 中的某一个数的二进制表示的第 i 位为 0,另一个数的第 i 位为 1,我们可以据此来将数组中的所有元素分类:

  • i 位为 1 的为一类;
  • i 位为 0 的为一类;

根据以上分类,我们知道 x 1 x_1 x1 x 2 x_2 x2 分属在以上两个类中。每个类中出现的数有一个数是仅出现一次的数,其他的数都是出现两次的。于是,我们对每一个类中的元素进行异或和操作,就得到了该类中仅出现一次的元素。对这两个类分别进行异或和操作就得到了数组 nums 中仅出现了一次的两个数。

实现代码

class Solution {
public:
    vector<int> singleNumber(vector<int>& nums) {
        int sum = 0;
        for(auto &num : nums){
            sum ^= num;
        }
        
        // 防止溢出
        int lst = ((sum == INT_MIN) ? sum : sum & (-sum));
        
        int num1 = 0, num2 = 0;
        for(auto &num : nums){
            if(lst & num){
                num1 ^= num;
            }
            else{
                num2 ^= num;
            }
        }
        return {num1, num2};
    }
};

复杂度分析

时间复杂度: n n n 是数组 nums 的长度。

空间复杂度: O ( 1 ) O(1) O(1)


其他语言

c

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* singleNumber(int* nums, int numsSize, int* returnSize){
    int xorsum = 0;
    for (int i = 0; i < numsSize; ++i) {
        xorsum ^= nums[i];
    }

    int lsb = (xorsum == INT_MIN ? xorsum : xorsum & (-xorsum));
    int x1 = 0, x2 = 0;
    for (int i = 0; i < numsSize; ++i) {
        int num = nums[i];
        if (num & lsb) {
            x1 ^= num;
        }
        else {
            x2 ^= num;
        }
    }

    int *res = (int *)malloc(sizeof(int) * 2);
    res[0] = x1;
    res[1] = x2;
    *returnSize = 2;
    return res;
}

python3

class Solution:
    def singleNumber(self, nums: List[int]) -> List[int]:
        xorsum = 0
        for num in nums:
            xorsum ^= num
        
        lsb = xorsum & (-xorsum)
        x1, x2 = 0, 0
        for num in nums:
            if num & lsb:
                x1 ^= num
            else:
                x2 ^= num
        return [x1, x2]

写在最后

如果文章内容有任何错误或者您对文章有任何疑问,欢迎私信博主或者在评论区指出 。

如果大家有更优的时间、空间复杂度方法,欢迎评论区交流。

最后,感谢您的阅读,如果感到有所收获的话可以给博主点一个 哦。

你可能感兴趣的:(LeetCode每日一题,位运算+异或和,数组,2023-10-16)