zoukankan      html  css  js  c++  java
  • 287. Find the Duplicate Number

    问题:

    给定一个包含n + 1个整数的数组,其中每一个整数均介于[1, n]之间,求重复的数字。

    Example 1:
    Input: [1,3,4,2,2]
    Output: 2
    
    Example 2:
    Input: [3,1,3,4,2]
    Output: 3
    
    Note:
    You must not modify the array (assume the array is read only).
    You must use only constant, O(1) extra space.
    Your runtime complexity should be less than O(n2).
    There is only one duplicate number in the array, but it could be repeated more than once.
    

      

    解法1: sort,找连续两个相同的,即为所求

    参考代码:

     1 class Solution {
     2 public:
     3     int findDuplicate(vector<int>& nums) {
     4         sort(nums.begin(),nums.end());
     5         for(int i=1; i<nums.size(); i++){
     6             if(nums[i]==nums[i-1]) return nums[i];
     7         }
     8         return 0;
     9     }
    10 };

    解法2: 将数组轮询,同时插入set中,每次插入前,find是否已存在,存在则为所求

     1 class Solution {
     2 public:
     3     int findDuplicate(vector<int>& nums) {
     4         unordered_set<int> tmp;
     5         for(int i:nums){
     6             if(tmp.find(i) == tmp.end()){
     7                 tmp.insert(i);
     8             }else{
     9                 return i;
    10             }
    11         }
    12         return 0;
    13     }
    14 };

    解法3: 快慢指针法:求回环相遇问题。

    a:链表起点到环入口的距离。黑色
    c:圆环的周长。蓝色+红色
    x:相遇结点到圆环起点的距离蓝色

    快结点走过的距离i为a+N1*c+x,(黑色+N1*(蓝色+红色)+蓝色

    慢结点走过的距离为a+N2*c+x。(黑色+N2*(蓝色+红色)+蓝色

    由于快结点的速度为慢结点的两倍(相同时间所走距离也为2倍)所以  a+N1*c+x = 2*(a+N2*c+x) 。

    最后得出a+x=c(N1-2N2)。

    N1代表快结点转过的圈数,N2代表慢结点转过的圈数。

    a+x=N个圈的周长,即 a(黑色)=N-1个周长+(周长-x)=N-1个周长+红色

    因此当快结点从链表起点出发(走黑色a的距离),慢结点以同样的速度从刚刚相遇的结点出发(走红色的距离+N-1个周长

    到它们会和,会和的结点一定是重复数字的结点。(蓝色红色黑色的交点)

    代码参考:

     1 class Solution {
     2 public:
     3     int findDuplicate(vector<int>& nums) {
     4         int fast=0, slow=0;
     5         fast=nums[nums[fast]];
     6         slow=nums[slow];
     7         while(fast!=slow){
     8             fast=nums[nums[fast]];
     9             slow=nums[slow];
    10         }
    11         fast=0;
    12         while(fast!=slow){
    13             fast=nums[fast];
    14             slow=nums[slow];
    15         }
    16         return slow;
    17     }
    18 };
  • 相关阅读:
    ubuntu 16.04 连接无线网络
    linux的内存管理-抛砖引玉
    linux的进程调度-抛砖引玉
    AliOS Things 异步事件框架Yloop
    AliOS Things 云端物联网操作系统
    linux performance tools
    linux进程调度
    linux 内核Lockup机制浅析
    cache和内存屏障
    linux设备模型及实例
  • 原文地址:https://www.cnblogs.com/habibah-chang/p/12637062.html
Copyright © 2011-2022 走看看