文章目录
- Tag
- 题目来源
- 题目解读
- 解题思路
- 方法一:位运算
 
- 其他语言
- c
- python3
 
- 写在最后
Tag
【位运算】【数组】【2023-10-16】
题目来源
260. 只出现一次的数字 III
 
 
题目解读
找出数组中恰好只出现一次的连个元素,其余的所有元素均出现两次。要求算法的时间复杂度为线性的,空间复杂度为常量级别的。
解题思路
方法一:位运算
我们先对数组 nums 中的虽有元素进行一次异或操作,得到的值 x 是数组中仅仅出现过一次的两个数的异或值,即  
     
      
       
       
         x 
        
       
         = 
        
        
        
          x 
         
        
          1 
         
        
       
         ⨁ 
        
        
        
          x 
         
        
          2 
         
        
       
      
        x = x_1 \bigoplus x_2 
       
      
    x=x1⨁x2, 
     
      
       
        
        
          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]
写在最后
如果文章内容有任何错误或者您对文章有任何疑问,欢迎私信博主或者在评论区指出 💬💬💬。
如果大家有更优的时间、空间复杂度方法,欢迎评论区交流。
最后,感谢您的阅读,如果感到有所收获的话可以给博主点一个 👍 哦。



















