剑指Offer 03 数组中重复的数字

找出数组中重复的数字。


在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。

示例 1:

输入:
[2, 3, 1, 0, 2, 5, 3]
输出:2 或 3
 

限制:

2 <= n <= 100000

 

1.排序后遍历

先对数字进行排序,然后遍历就可以得出结果,时间复杂度为O(nlogn)。

 

2.哈希表

使用哈希表记录出现过的数字,遇到新数时如果哈希表中已经存在该数,则找到。

时间复杂度为O(n),空间复杂度为O(n)。

 

3.利用所有数都在0-n-1的区间

如果没有重复的数,那么所有数都应该在和它们值相等的下标上,那么我们从头循环,遇到一个数就把它交换到它对应的坐标,当遇到该坐标已经有目标数的时候就找到了重复的数。

 1 class Solution {
 2 public:
 3     int findRepeatNumber(vector<int>& nums) {
 4         int n=nums.size();
 5         int i=0;
 6         while(i<n){
 7             if(nums[i]!=i){
 8                 if(nums[i]==nums[nums[i]])
 9                     return nums[i];
10                 swap(nums[i],nums[nums[i]]);
11             }
12             else i++;
13         }
14         return 0;
15     }
16 };

 

第二次做看还是有点问题,对于错误情况处理的不太好,应该要throw exception或者设置全局变量。

 1 class Solution {
 2 public:
 3     enum Status{kValid=0,KinValid};
 4     int g_repeatStates=kValid;
 5     int findRepeatNumber(vector<int>& nums) {
 6         if(nums.size()<2){
 7             g_repeatStates=KinValid;
 8             return 0;
 9         }
10         int pos=0;
11         for(;pos<nums.size();){
12             if(nums[pos]==pos)
13                 ++pos;
14             else{
15                 if(nums[nums[pos]]==nums[pos]){
16                     return nums[pos];
17                 }
18                 swap(nums[nums[pos]],nums[pos]);
19             }
20         }
21         g_repeatStates=KinValid;
22         return 0;
23     }
24 };

 

posted @ 2020-07-01 21:49  __rookie  阅读(181)  评论(0编辑  收藏  举报