0
点赞
收藏
分享

微信扫一扫

Node.js 中间件是怎样工作的?

七千22 2023-09-04 阅读 63

❓剑指 Offer 56 - I. 数组中数字出现的次数

难度:中等

一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是 O ( n ) O(n) O(n),空间复杂度是 O ( 1 ) O(1) O(1)

示例 1:

示例 2:

限制

  • 2 <= nums.length <= 10000

💡思路:位运算

两个相等的元素 异或 的结果为 0,而 0 与任意数 x 异或 的结果都为 x

对本题给的数组的所有元素执行异或操作,得到的是两个不存在重复的元素异或的结果。例如对于数组 [x,x,y,y,z,k]x^x^y^y^z^k = 0^y^y^z^k = y^y^z^k = 0^z^k = z^k

两个不相等的元素在位级表示上一定会有所不同,因此这两个元素异或得到的结果 diff 一定不为 0:

  • 使用 ans[0] = diff 先保存这两个数的结果;
  • 位运算 diff & -diff 能得到 diff 位级表示中 最右侧为 1 的位,令 diff = diff & -diff
  • diff 作为区分两个元素的依据,一定有一个元素对 diff 进行 运算的结果为 diff ,另一个结果为 0。

设不相等的两个元素分别为 xy,遍历数组所有元素,判断每一个元素与 diff 结果是否为 diff :

  • 如果是的话将元素与 x 进行 异或 并赋值给 ans[1]
  • 数组中相等的元素一定会同时与 x 异或操作,而且这些相等的元素异或的结果为 0,因此最后 只剩下 x 与 0 异或的结果;
  • 另一个元素 y = ans[0] ^ x

🍁代码:(C++、Java)

C++

class Solution {
public:
    vector<int> singleNumbers(vector<int>& nums) {
        vector<int> ans(2);
        int diff = 0;
        for(int num : nums){//得到只出现一次的两个数的异或
            diff ^= num;
        }
        ans[0] = diff; //记录两个数的异或结果
        diff &= -diff; //得到最后一位1
        for(int num : nums){//得到其中一个数
            if((num & diff) == diff){
                ans[1] ^= num; 
            }
        }
        ans[0] ^= ans[1];//得到另一个数
        return ans;
    }
};

Java

class Solution {
    public int[] singleNumbers(int[] nums) {
        int[] ans = new int[2];
        int diff = 0;
        for(int num : nums){//得到只出现一次的两个数的异或
            diff ^= num;
        }
        ans[0] = diff; //记录两个数的异或结果
        diff &= -diff; //得到最后一位1
        for(int num : nums){//得到其中一个数
            if((num & diff) == diff){
                ans[1] ^= num; 
            }
        }
        ans[0] ^= ans[1];//得到另一个数
        return ans;
    }
}

🚀 运行结果:

在这里插入图片描述

🕔 复杂度分析:

  • 时间复杂度 O ( n ) O(n) O(n),我们只需要遍历数组两次。
  • 空间复杂度 O ( 1 ) O(1) O(1),只需要常数的空间存放若干变量。

题目来源:力扣。

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

举报

相关推荐

0 条评论