剑指offer56(Java)-数组中出现的次数Ⅰ(中等)

发布时间 2023-04-06 14:38:41作者: 我不想一直当菜鸟

题目:

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

 示例 1:

输入:nums = [4,1,4,6]

输出:[1,6] 或 [6,1]

示例2:

输入:nums = [1,2,10,4,1,4,3,3]

输出:[2,10] 或 [10,2]

限制:

  • 2 <= nums.length <= 10000

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路:

暴力求解:哈希表,但是不符合空间复杂度

先用哈希表统计出每个数字出现的次数,由于只有两个数字出现了一次,然后遍历哈希表,将出现一次的数字放入长度为2 的数组中返回即可。

 1 class Solution {
 2     public int[] singleNumbers(int[] nums) {
 3         Map<Integer,Integer> map = new HashMap<>();
 4         int i = 0;
 5         for(int num : nums){
 6             map.put(num, map.getOrDefault(num,0) + 1);
 7         }
 8         int[] ans = new int[2];
 9         for (Integer key: map.keySet()){
10             if (map.get(key) == 1) {
11                 ans[i] = key;
12                 i++;
13             }
14         }
15         return ans;
16     }
17 }

 异或:

异或公式:

① 交换律:A ^ B ^ C = A ^C ^ B

② A^ A = 0

③ A ^ 0 = A

故一个数组的元素进行异或:

比如:[2,4,2,3,3,6]  异或:2^4^2^3^3^6 = 4 ^ 6 ^(2^2)^(3^3) = 4 ^ 6 = 0100 ^ 0110 =  0010

思路:

①先将数组中的所有值进行异或,得到异或结果xor:

 ②设第一个为1的二进位为最后一位即0001,即设m = 1,让 m 不断左移来与xor做 与运算(相同为1)来找到第一位为1 的二进制位:

例如:

若x&0001=1,则a 的第一位为1,

若x&0010=1,则a 的第二位为1;

以此类推……

③根据num ^ m 是否等于0来差分数组。

具体过程可以看:K神老师以及评论区的解释

 代码:

 1 class Solution {
 2     public int[] singleNumbers(int[] nums) {
 3         int xor = 0;
 4         //计算所有值的异或结果
 5         for (int num : nums){
 6             xor ^= num;
 7         }
 8         int m = 1;
 9         //找到第一位为1的二进制位,即当 m & xor = 1,保存m
10         while ((m & xor) == 0){
11             //m左移1位
12             m <<= 1;
13         }
14         //利用m来将数组分组
15         //[4,1,4,6] xor = 1 ^ 6 = 0111,m = 0001 
16         //num & m = 0的为一组:[4,4,6]
17         //num & m = 1的为一组:[1]
18         int x = 0, y = 0;
19         for (int num : nums){
20             if ((num & m) == 0){ 
21                 x ^= num;
22             
23             }
24             else{
25                  y ^= num;
26             }
27         }
28         return new int[]{x,y};
29     }
30 }