[219].存在重複元素 II

 


題目

給定一個整數數組和一個整數 k,判斷數組中是否存在兩個不同的索引 ij,使得 nums[i]=nums[j]nums [i] = nums [j],並且 ij 的差的 絕對值 至多爲 k

示例 1:

輸入: nums = [1,2,3,1], k = 3
輸出: true

示例 2:

輸入: nums = [1,0,1,1], k = 1
輸出: true

示例 3:

輸入: nums = [1,2,3,1,2,3], k = 2
輸出: false

 


函數原型

C 的函數原型:

bool containsNearbyDuplicate(int* nums, int numsSize, int k){}

 


邊界判斷

bool containsNearbyDuplicate(int* nums, int numsSize, int k){
	if( nums == NULL || numsSize == NULL )
		return false;
}

 


算法設計:滑動窗口 + 查找表

nums[i]=nums[j]nums [i] = nums [j],並且 ij 的差的 絕對值 至多爲 k

也就是說 nums[i]nums[j]nums [i] 、nums [j] 存儲的是同一個元素。

因爲 ji<=kj-i <= k,那它們一定在某個區間 [l, l+k][l,~ l+k] 裏:

這個區間有 k+1k+1 個元素,如果在 k+1k+1 個元素中,能找到倆個相同的元素,不就滿足 ji<=kj-i <= k 啦。

所以,問題就是:在這個數組中,能不能找到某個區間,這個區間存在倆個相同的元素。

思路:找一個範圍使得其值滿足某個條件,然後就會想到滑動窗口。

假設查找的是這樣一個區間:

當前區間並沒有相同元素,所以要去看下一個元素(向右擴展)


看下一個元素的同時,爲了維持窗口範圍,左邊也得收縮一下:

而後考慮的是,新元素(紅色)在區間 [l+1, l+k][l+1,~l+k] 中有木有相同的元素。

倆種情況:

  • 有相同元素,即找到了,的確存在這樣的區間
  • 沒有相同元素,就繼續找,直到找遍整個數組,說明沒有這樣的區間
#include<uthash.h>		/* C語言哈希庫 */

typedef struct hash{
    int key;  // 鍵
    int index;  // 索引值
    UT_hash_handle hh; // 讓結構體哈希柄
} *hash_ptr;

bool containsNearbyDuplicate(int* nums, int numsSize, int k){
    hash_ptr p = NULL, tables = NULL;
    for(int i=0; i<numsSize; i++){
    
        if( tables ) 
        	HASH_FIND_INT(tables, &(nums[i]), p);
        	
        if( p && (i-p->index) <= k ) 
        	return true;
        	
        p=(hash_ptr)malloc(sizeof(*p));
        p->key=nums[i];
        p->index=i;
        HASH_ADD_INT(tables, key, p);
    }
    
    free(p), p = NULL;
    return false;
}
  • 時間複雜度:Θ(n)\Theta(n)
  • 空間複雜度:Θ(min(n,k))\Theta(min(n, k))
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章