The purpose of writing this column is mainly to provide some ideas for solving problems. If there are any deficiencies, please correct me! ! !
Question:
Given an array of integersnums
and an integerk
, determine whether there are two different indicesi
and in the arrayj
, satisfyingnums[i] == nums[j]
andabs(i - j) <= k
. If it exists, return ittrue
; otherwise, return itfalse
.
Example 1:
输入:nums = [1,2,3,1], k = 3
输出:true
Example 2:
输入:nums = [1,0,1,1], k = 1
输出:true
Example 3:
输入:nums = [1,2,3,1,2,3], k = 2
输出:false
hint:
- 1 <= nums.length <= 105
- 109 <= nums[i] <= 109
- 0 <= k <= 105
This question is an extended version of 217. There are repeated elements .
Solution 1: Brute force cracking method
This way of writing is indeed violent and not elegant. . .
/**
* @param {number[]} nums
* @param {number} k
* @return {boolean}
*/
var containsNearbyDuplicate = function(nums, k) {
// 1、去重
const newNums = [...new Set(nums)];
// 2、比较元素组和去重后素组的长度,如果长度不相等,表明存在重复元素,继续往下走;否则,返回false
if (nums.length !== newNums.length) {
for (let i = 0; i < newNums.length; i++) {
const array = [];
for (let j = 0; j < nums.length; j++) {
// 3、找到值相同的元素,并在array里放入相同元素的下标
if (newNums[i] === nums[j]) {
array.push(j);
}
}
// 4、如果array数组的长度大于2(存在重复元素),通过遍历存入的下标,满足abs(i - j) <= k返回true
if (array.length >= 2) {
for (let s = 0; s < array.length - 1; s++) {
if (Math.abs(array[s] - array[s + 1]) <= k) {
return true;
}
}
}
}
}
return false;
};
Solution 2: Hash table
If you Map
are not familiar with the right method, you can move here .
/**
* @param {number[]} nums
* @param {number} k
* @return {boolean}
*/
var containsNearbyDuplicate = function(nums, k) {
const map = new Map();
for(let i = 0; i < nums.length; i++) {
const num = nums[i];
// 如果map存在num(存在重复元素)并且重复元素下标的差值小于k
// 这里不用绝对值是因为i一定大于map.get(num)
if (map.has(num) && i - map.get(num) <= k) {
return true;
}
map.set(num, i);
}
return false;
};
Solution 3: Sliding window
Idea: The title requires that the subscript difference between two identical values must be less than or equal to k
, that is abs(i - j) <= k
, it can be simply understood as the effective range k
.
Take example 1 as an example:
nums = [1,2,3,1]
, k = 3
that is to say, set
the size
largest is 4
, because the subscript 3
and the subscript 0
are actually 4
an element, after saving 1、2、3
, the next one is 1
, at this time, it is found set
that there are equal 1
and satisfying conditions, return directly true
.
Take example 3 as an example: nums = [1,2,3,1,2,3]
, k = 2
similarly, set
the size
maximum is 3
, that is to say, starting from nums
the first 4
element (that is 1
), it is already exceeded set
. size
At this time, the first element needs to be deleted, which can be imagined as The slider with a length 3
of is sliding to the right. If there are the same elements within the length of the slider, it is eligible.
/**
* @param {number[]} nums
* @param {number} k
* @return {boolean}
*/
var containsNearbyDuplicate = function(nums, k) {
const set = new Set();
for(let i = 0; i < nums.length; i++) {
// 如果i大于k,说明超过了满足条件的范围,需要删除set最前面的元素
if (i > k) {
set.delete(nums[i-k-1]);
}
// 如果存在重复元素
if (set.has(nums[i])) {
return true;
}
set.add(nums[i]);
}
return false;
};
If you Set
still have questions, you can move here .
Here are just a few common solutions. If there is a better solution, you are welcome to add it!