1. 程式人生 > >leetcode-219-Contains Duplicate II(使用set來判斷長度為k+1的閉區間中有沒有重復元素)

leetcode-219-Contains Duplicate II(使用set來判斷長度為k+1的閉區間中有沒有重復元素)

復雜度 存在 限制 ret ras out ++ 出現 mis

題目描述:

Given an array of integers and an integer k, find out whether there are two distinct indices i and j in the array such that nums[i] = nums[j] and the absolute difference between i and j is at most k.

Example 1:

Input: [1,2,3,1], k = 3
Output: true

Example 2:

Input: [1,0,1,1], k =1
Output: true

Example 3:

Input: [1,2,1], k =0
Output: false

要完成的函數:

bool containsNearbyDuplicate(vector<int>& nums, int k)

說明:

1、這道題給定一個vector和一個整數k,要求判斷能不能找到兩個不同位置的相同元素,他們的位置分別是i和j,使得i-j的絕對值不超過k。

2、這道題相比起上一道“找到兩個重復的元素”,增加了距離k的限制。

首先,我們能夠判斷如果k<=0,那麽必定是不存在兩個不同位置的相同元素的。

其次,如果k>=nums.size()-1,那麽這道題也就是上一道“找到兩個重復的元素”的做法。

所以我們只需要關註k<nums.size()這種情況下,我們要如何判斷。

最簡單最暴力的方法當然是雙重循環,設定窗口長度為k+1,從nums的第一位開始,判斷窗口內有沒有跟首元素相同的元素。

接著窗口不斷往後挪,去掉第一個元素,增加一個新的元素,判斷窗口的首元素,也就是這時候nums的第二個元素,有沒有在窗口內出現重復元素。

這種做法時間復雜度O(n^2)

我們也可以仍然往後挪窗口,只不過使用set,用哈希的方法來判斷窗口中有沒有重復元素,這種判斷比起上述暴力方法快了許多。

時間復雜度大致是O(n),因為哈希的時間時間復雜度是O(1)?

代碼如下:(附詳解)

    bool containsNearbyDuplicate(vector<int>& nums, int k) 
    {
        int s1=nums.size();
        if(k<=0)//邊界條件
            return false;
        if(k>=s1-1)//轉化為上一道題,“找到兩個重復的元素”
        {
            sort(nums.begin(),nums.end());
            for(int i=0;i<s1-1;i++)
            {
                if(nums[i]==nums[i+1])
                    return true;
            }
            return false;
        }
        unordered_set<int>set1(nums.begin(),nums.begin()+k+1);//使用set來存儲,初始化其中有k+1個元素
        if(set1.size()!=k+1)//初始情況下的判斷
            return true;
        for(int i=k+1;i<s1;i++)
        {
            set1.erase(nums[i-k-1]);//刪去首位元素
            set1.insert(nums[i]);//增加後一位新的元素,這個插入過程其實包含了判斷有沒有重復,決定要不要插入到set中
            if(set1.size()!=k+1)//用set的size來判斷
                return true;
        }
        return false;
        
    }

上述代碼實測24ms,beats 97.46% of cpp submissions。

leetcode-219-Contains Duplicate II(使用set來判斷長度為k+1的閉區間中有沒有重復元素)