给你一个整数数组 nums 和一个整数 k ,判断数组中是否存在两个 不同的索引 i 和 j ,满足 nums[i] == nums[j] 且 abs(i - j) <= k 。如果存在,返回 true ;否则,返回 false 。
示例 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
提示:
- 1 <= nums.length <= 10^5
- -10^9 <= nums[i] <= 10^9
- 0 <= k <= 10^5
分析:
方法1:暴力解法
遍历时每隔 k 个数就比较一次,发现重复直接返回 true,遍历完没有重复数就 k - 1 继续遍历,直到 k = 0。
时间复杂度:O(k * n)
空间复杂度:O(n)
class Solution {
public boolean containsNearbyDuplicate(int[] nums, int k) {
//记录数组长度
int len = nums.length;
while(k > 0){
//遍历
for(int i = 0; i < len - k; ++i){
//发现重复数
if(nums[i] == nums[i+k]){
return true;
}
}
k--;
}
return false;
}
}
方法2:哈希表
利用哈希表降低数据的存储和查找消耗的时间的优点,我们可以将这间隔的 k 个数存入哈希表中,当添加下一个数时,如果哈希表的大于 k,那就把最开始的数移除,将新数添加。
时间复杂度:O(n)
空间复杂度:O(k+1)
class Solution {
public boolean containsNearbyDuplicate(int[] nums, int k) {
//记录数组长度
int len = nums.length;
//创建哈希表
Set<Integer> set = new HashSet<Integer>();
//遍历
for(int i = 0; i < len; ++i){
//发现重复数,返回true
if(set.contains(nums[i])){
return true;
}
//添加新数
set.add(nums[i]);
//长度大于 k 时删除最开始添加的数
if(set.size() > k){
set.remove(nums[i - k]);
}
}
return false;
}
}
题目来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/contains-duplicate-ii