【剑指offer】59.数组中只出现一次的两个数字

总目录:

算法之旅导航目录

 

1.问题描述

一个整型数组里除了两个数字只出现一次,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
数据范围:数组长度 2n1000,数组中每个数的大小0<val1000000
要求:空间复杂度 O(1),时间复杂度 O(n)
提示:输出时按非降序排列。

 

2.问题分析

1哈希

迭代元素,查看哈希表中是否有该元素,有则从哈希表中删去,没有则插入,最后将哈希表中的内容导出并排序

2位比较

数字异或自身=0,且异或满足交换律

将所有数字异或在一起,得到的是那两个独立数字的异或值,

问题是如何将这两个数字分开?这两个数字至少有1位不同,用那一位数字将整个集合分成两部分,两部分内的数字全部异或在一起,将分别得到2个独立数字。(太巧妙了)


3.代码实例

哈希

 1 class Solution {
 2   public:
10     vector<int> FindNumsAppearOnce(vector<int>& array) {
11         unordered_set<int> set;
12         for (int i = 0; i < array.size(); i++) {
13             if (set.find(array[i]) != set.end()) {
14                 set.erase(array[i]);
15             } else {
16                 set.insert(array[i]);
17             }
18         }
19 
20         vector<int> ret;        
21         for (auto j :set) {
22             ret.push_back(j);
23         }
24         if(ret[0]>ret[1]){
25             swap(ret[0],ret[1]);
26         }
27 
28         return ret;
29     }
30 };

位运算

 1 class Solution {
 2   public:
 3     /**
 4      * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 5      *
 6      *
 7      * @param array int整型vector
 8      * @return int整型vector
 9      */
10     vector<int> FindNumsAppearOnce(vector<int>& array) {
11         // 先将全部数进行异或运算,得出最终结果
12         int tmp = 0;
13         for (int num : array) {
14             tmp ^= num;
15         }
16 
17         // 找到那个可以充当分组去进行与运算的位
18         // 从最低位开始找起
19         int mask = 1;
20         while ((tmp & mask) == 0) {
21             mask <<= 1;
22         }
23 
24         // 进行分组,分成两组,转换为两组 求出现一次的数字 去求
25         int a = 0;
26         int b = 0;
27         for (int num : array) {
28             if ((num & mask) == 0) {
29                 a ^= num;
30             } else {
31                 b ^= num;
32             }
33         }
34 
35         //排序
36         vector<int> ret;
37         ret.push_back(a < b ? a : b);
38         ret.push_back(a < b ? b : a);
39         return ret;
40     }
41 };

 

posted @ 2022-12-02 19:47  啊原来是这样呀  阅读(22)  评论(0编辑  收藏  举报