Question
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 difference between i and j is at most k.
思路一
暴力破解,用两个for循环,毫无疑问超时了;
代码
public class Solution {
/**
* 查看数组内是否有重复元素且相邻重复元素索引间隔不大于K
* @param nums
* @return
*/
public boolean containsNearbyDuplicate(int[] nums, int k) {
if (nums.length <= 1) {
return false;
}
for (int i = 0; i < nums.length; i++) {
for (int j = i + 1; j <= i + k && j < nums.length; j++) {
if (nums[i] == nums[j]) {
return true;
}
}
}
return false;
}
}
思路二
用hashmap,hashmap内保存该元素出现的最后的位置,从前往后依次遍历,然后查看map里保存的该元素出现的最后的位置,然后和现在的位置去比较。
代码
public class Solution {
public boolean containsNearbyDuplicate(int[] nums, int k) {
Map<Integer,Integer> last_position = new HashMap<>();
for(int i = 0;i < nums.length;i++){
if(!last_position.containsKey(nums[i]))
last_position.put(nums[i],i);
else{
int last_po = last_position.get(nums[i]);
if(i - last_po <= k)
return true;
else
last_position.put(nums[i],i);
}
}
return false;
}
}
结果
超时了
改进
其实这个思路是对的,只要改进一下就对了
public class Solution {
public boolean containsNearbyDuplicate(int[] nums, int k) {
Map<Integer,Integer> last_position = new HashMap<>();
for(int i = 0;i < nums.length;i++){
if(last_position.containsKey(nums[i]) && (i - last_position.get(nums[i]) <= k))
return true;
last_position.put(nums[i],i);
}
return false;
}
}
二刷思路三
set是java的一种数据结构,不能允许重复的数据出现,如果数据重复则返回false,不能被加入到set中。我们可以利用这个特性,在set中只保留k个数字,如果不能加入到set中,说明k个数字中有重复的,返回true即可。
代码
public class Solution {
public boolean containsNearbyDuplicate(int[] nums, int k) {
Set<Integer> set = new HashSet();
for(int i = 0;i < nums.length;i++){
if(i > k)
set.remove(nums[i - k - 1]);
if(!set.add(nums[i]))
return true;
}
return false;
}
}