题目
- 给定一个整数数组和一个整数 k,判断数组中是否存在两个不同的索引 i 和 j,使得 nums [i] = nums [j],并且 i 和 j 的差的绝对值最大为 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
说明
①数据范围(自测)
②相关话题
③相似题目
④题目地址
解题方法
①暴力解法
- 两层 for 循环暴力判断。
- 时间复杂度:O(N^2)。
- 空间复杂度:O(1)。
②滑动窗口 + 哈希表
- 这道题的数据范围很大,每组数据值的波动幅度也很大,所以不能用数组模拟的哈希表求解,需要使用 uthash。
- uthash 是一个用 C 语言编写的开源库,使用宏实现了哈希表的增删改查等功能。
- 我们需要使用滑动窗口和查找表,不断地查找当前哈希表中有没有重复值。并且当窗口的大小大于 k 时,需要移除哈希表中最左边的元素,保证窗口中最多有 k 个元素。
- 时间复杂度:O(N)。
- 空间复杂度:O(N)。
代码详解
bool containsNearbyDuplicate(int* nums, int numsSize, int k) {
for (int i = 0; i < numsSize; i++) {
int limit = i+k >= numsSize? numsSize: i+k+1;
for (int j = i+1; j < limit; j++) {
if (nums[j] == nums[i])
return true;
}
}
return false;
}
bool containsNearbyDuplicate(int* nums, int numsSize, int k) {
struct hash {
int value;
UT_hash_handle hh;
};
struct hash *hashTable = NULL;
int len = 0;
for (int i = 0; i < numsSize; i++) {
struct hash *h;
if (len > k) {
HASH_FIND_INT(hashTable, nums+len-k-1, h);
HASH_DEL(hashTable, h);
h = NULL;
}
HASH_FIND_INT(hashTable, nums+i, h);
if (h)
return true;
else {
h = malloc(sizeof(struct hash));
h->value = nums[i];
HASH_ADD_INT(hashTable, value, h);
len++;
}
}
return false;
}
附录