leetcode 287寻找重复数

 

这道题用STL容器就很好写了,可以用set也可以用map,

用unordered_map的C++代码如下:

 1 class Solution {
 2 public:
 3     int findDuplicate(vector<int>& nums) {
 4         unordered_map<int, int> m;
 5         int res;
 6         for(int i=0;i<nums.size();i++){
 7             if(m.count(nums[i])){
 8                 res=nums[i];break;
 9             }
10             m[nums[i]]=i;
11         }
12         return res;
13     }
14 };

12ms beat 44%

 

使用set:

 1 class Solution {
 2 public:
 3     int findDuplicate(vector<int>& nums) {
 4         set<int> s;
 5         int res;
 6         for(int i=0;i<nums.size();i++){
 7             if(s.find(nums[i])!=s.end()){
 8                 res=nums[i];break;
 9             }
10             s.insert(nums[i]);
11         }
12         return res;
13     }
14 };

16ms beat 33%

C++ 二分法:

但是,但是,但是,题目要求time O(n2) space O(1) 说明这道题要时间换空间,那么使用二分法:

timeO(nlog(n)) spaceO(1): 1 2 2 3 5 4对于某个数x,如果小于等于他的数出现次数大于他,说明重复数在【low,x】之间,如小于等于2的数有3个,那么重复数在【1,2】之间;小于等于1的数只有1个,那么在【2,2】之间,从而得解

class Solution {
public:
    int findDuplicate(vector<int>& nums) {
        //二分法
        /*理论分析,所有的数出现的次数总和加起来为n+1==len,计mid=(low+high)/2;那么当小于mid出现次数大于mid时,则重复数在mid左边*/
        int len=nums.size();
        int low=1,high=len-1;
        while(low<high){
            int mid=low+(high-low)/2,cnt=0;
            for(int num:nums)
                if(num<=mid) cnt++;
            if(cnt>mid)
                high=mid;
            else
                low=mid+1;
        }
        return low;
    }
};

 快慢指针:

class Solution {
public:
    int findDuplicate(vector<int>& nums) {
        int n=nums.size()-1;
        if(n<1) return 1;
        int slow = nums[0];
        int fast = nums[nums[0]];
        //vector<int> fs={fast},ss={slow},ts;
        while (slow != fast)
        {
            slow = nums[slow];
            fast = nums[nums[fast]];
            //fs.push_back(fast);
            //ss.push_back(slow);
        }

        int target=0;
        
        while (target != slow){
            slow=nums[slow];
            target=nums[target];
            //ts.push_back(target);
            //ss.push_back(slow);
        }
        /*
        cout<<"fs: ";
        for(int n:fs)
            cout<<n<<",";
        cout<<endl;
        cout<<"ss: ";
        for(int n:ss)
            cout<<n<<",";
        cout<<endl;
        cout<<"ts: ";
        for(int n:ts)
            cout<<n<<",";
        cout<<endl;*/
        return target;
    }
};

 

posted @ 2019-01-30 20:00  Joel_Wang  阅读(233)  评论(0编辑  收藏  举报