剑指 Offer 03. 数组中重复的数字

剑指 Offer 03. 数组中重复的数字:

方法一:利用空间换时间。哈希表

class Solution {
public:
    int findRepeatNumber(vector<int>& nums) {
        vector<int> hashNum;
        int ans;
        int len = nums.size();
        hashNum.resize(len,0);
        for(int i=0;i<len;i++){
            if(hashNum[nums[i]] == 0){
                hashNum[nums[i]]++;
            }else{
                ans = nums[i];
                break;
            }  
        }
        return ans;
    }
};

解法二:原地置换

我们注意到数组中数字都在0~n-1的范围内。如果这个数组中没有重复的数字,那么当数组排序之后数字i将出现在下标为i的位置。
由于数组中有重复的数字,有些位置可能存在多个数字,同时有些位置可能没有数字。我们利用这个规律来查重。

以数组{2,3,1,0,2,5,3}为例来分析找到重复数字的步骤。
数组的第0个数字(从0开始计数,和数组的下标保持一致)是2,
那么我们检查第2个数字。如果第2个数字也是2,那么查重成功。否则,我们交换这两个下标的数字。(相当于排序,至少数字2放在了大概正确的位置)。
经过这样重复操作,有一部分已经有序,往后继续检索(操作),那么终究会查出来重复的数字。

代码如下:

class Solution {
public:
    int findRepeatNumber(vector<int>& nums) {
        int ans;
        int len = nums.size();
        int temp,j;
        for(int i=0;i<len;i++){
            while(nums[i]!=i){
                
                j = nums[i];
                if(nums[j] == j){
                    ans = j;
                    return j;
                }
                temp = nums[j];
                nums[j] = j;
                nums[i] = temp;
            }
        }
        return ans;
    }
};
复杂度分析:

代码中尽管有一个两重循环,但是每个数字最多只要交换两次就能找到属于它自己的位置,因此总的时间复杂度是O(n)。另外,所有操作步骤都是在输入数组上进行的,空间复杂度为常熟级别的O(1)。

posted @ 2021-03-01 13:19  focusDing  阅读(62)  评论(0编辑  收藏  举报