剑指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 };