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 };
  • 相关阅读:
    通过URL地址将图片保存到本地
    Sql批量提交方法
    MySql 批量提交方法
    【Sqlserver】查看所有数据库的大小 创建日期 名称 版本级别 状态
    【asp.net】滑块验证码(分享一个从github上下载的源码)
    【winform】 WeifenLuo.WinFormsUI.Docking.dll 组件学习
    【C#】初次使用webapi的体会
    【C#】 封装的异步HttpRequest
    Android实现双时间选择器
    Android的金额3位数加逗号分隔
  • 原文地址:https://www.cnblogs.com/habibah-chang/p/12637062.html
Copyright © 2011-2022 走看看