这是我参与2022首次更文挑战的第7天,活动详情查看:2022首次更文挑战
前言
有人相爱,有人夜里开车看海,有人leetcode第一题都做不出来,由此可见,leetcode的题还是有分量的。今天我们就来会会它们
题目介绍
给你一个整数数组 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 <= 105
-109 <= nums[i] <= 109
0 <= k <= 105
哈希表
思路
- 首先定义一个空对象
obj(js中的对象就是基于哈希构建的) - 循环遍历数组
nums,获取到下标对应的值 - 判断当前循环的下标值是否存在对象
obj中 - 如果不存在,那么就把
当前循环的值作为键,值为当前循环的下标存入对象obj中 - 如果存在 那么判断当前索引的下标
减去对象obj[当前循环的下标]对应的值(这个值是循环的下标)是否小于等于k,那么返回true,否则返回false
解法一
var containsNearbyDuplicate = function (nums, k) {
const obj = {}
for (let i = 0; i < nums.length; i++) {
const item = nums[i]
if (obj[item] > -1 && i - obj[item] <= k) {
return true
} else {
obj[item] = i
}
}
return false
}
解法二
var containsNearbyDuplicate = function (nums, k) {
const map = Object.create(null)
for (let i = 0; i < nums.length; i++) {
const item = nums[i]
if (map[item] > -1 && i - map[item] <= k) {
return true
}
map[item] = i
}
return false
};
说明
解法一和解法二都利用了js对象的特性实现解法二的区别是使用Object.create(null)方法创建的对象- 而
解法一创建对象是通过对象字面量,他俩的区别,大家可以看我leetcode第一题的解法三,leetCode-俩数之和-4种解法
解法三
var containsNearbyDuplicate = function (nums, k) {
const map = new Map()
for (let i = 0; i < nums.length; i++) {
const item = nums[i]
if (map.has(item) && i - map.get(item) <= k) {
return true
}
map.set(item, i)
}
return false
};
说明
解法三本质也是利用了哈希表的原理实现的解法三则是通过es6的Map方法实现的
滑动窗口
介绍
Sliding window algorithm is used to perform required operation on specific window size of given large buffer or array.
滑动窗口算法是在给定特定窗口大小的数组或字符串上执行要求的操作。
This technique shows how a nested for loop in few problems can be converted to single for loop and hence reducing the time complexity.
该技术可以将一部分问题中的嵌套循环转变为一个单循环,因此它可以减少时间复杂度。
简单来说,滑动窗口算法就是在一个特定大小的字符串或数组上进行操作,而不在整个字符串和数组上操作,这样就降低了问题的复杂度,从而也达到降低了循环的嵌套深度。
思路
- 首先定义一个空数组
- 循环数组
nums,判断当前下标是否大于k - 如果小于等于
- 判断循环中的当前值在数组
arr中是否存在 - 如果存在
- 则证明符合要求,返回
true
- 则证明符合要求,返回
- 否则
- 把当前值添加到数组
arr中,进行下一次循环
- 把当前值添加到数组
- 判断循环中的当前值在数组
- 如果大于,那么就把数组的
第0项删掉(这样数组的长度就固定了),继续执行后续操作
解法一
var containsNearbyDuplicate = function (nums, k) {
const arr = []
for (let i = 0; i < nums.length; i++) {
if (i > k) {
arr.shift()
}
if (arr.indexOf(nums[i]) !== -1) {
return true
}
arr.push(nums[i])
}
return false
}
解法二
var containsNearbyDuplicate = function (nums, k) {
const arr = new Set()
for (let i = 0; i < nums.length; i++) {
if (i > k) {
arr.delete(nums[i-k-1])
}
if (arr.has(nums[i])) {
return true
}
arr.add(nums[i])
}
return false
}
说明
解法一利用了数组的特性解法二的思路其实和解法一是一样的,不过解法二采用的是es6的Set数据结构
写在最后
- 这篇文章虽然写的是
存在重复元素的解法 - 其中也涉及了一些
js书写的注意点 - 希望你也能收获满满