287. 寻找重复数
1 使用数组中的值作为索引下标进行遍历,遍历的结果肯定是一个环(有一个重复元素) 2 检测重复元素问题转换成检测环的入口 3 为了找到环的入口,可以进行如下步骤: 4 5 设置两个快慢指针, fast每次走两步,slow每次走一步,最终走了slow走了n步与fast相遇,fast走了2*n,fast可能比slow多饶了环的i圈,得到环的周长为n/i 6 slow指针继续走, 且另设第三个指针每次走一步,两个指针必定在入口处相遇 7 假设环的入口和起点的距离时m 8 当第三个指针走了m步到环的入口时 9 slow刚好走了n + m步,换句话说时饶了环i圈(环的周长为n/i)加m步(起点到入口的距离) 10 得到相遇的是环的入口,入口元素即为重复元素 11 12 class Solution 13 { 14 public: 15 int findDuplicate(vector<int>& nums) 16 { 17 int fast = 0,slow = 0; 18 while(true) 19 { 20 fast = nums[nums[fast]]; 21 slow = nums[slow]; 22 if(fast == slow) break; 23 } 24 fast = 0; 25 while(true) 26 { 27 fast = nums[fast]; 28 slow = nums[slow]; 29 if(fast == slow) break; 30 } 31 return slow; 32 } 33 };
//[1,3,4,2,2] //n个抽屉放入n+1个数,肯定有一个数重合 //[1,2,3,4] [l,mid] = [1,2]的数有三个 > mid-l+1,更新r = mid class Solution { public: int findDuplicate(vector<int>& nums) { int n = nums.size() - 1; int l = 1,r = n; while(l < r) { int mid = l + r >> 1; int cnt = 0; for(auto x : nums)//找到[l,mid]中的个数 { if(x >= l && x <= mid) cnt++; } if(cnt > mid - l + 1) r = mid; else l = mid + 1; } return r; } };
Mamba never out

浙公网安备 33010602011771号