hot100之哈希
在热门100中, 以下三题适用于哈希解决
哈希在js中可以简单理解为就是键值对, 可以是Object/Array/Map/Set.
哈希为什么能解决这类问题, 就是利用键找到对应值的时间复杂度为O (1).
两数之和(第1题easy)
题目描述
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。 你可以按任意顺序返回答案。
解题
原理: 遍历数组, 判断哈希中是否有差值, 如果有则找到答案, 如果没有则将当前值存入哈希
// 也可以存入差值, 判断当前值是否存在
var twoSum = function (nums, target) {
// 初始化哈希表
const map = new Map()
for (let i = 0; i < nums.length; i++) {
const now = nums[i]
// 和目标值的差值
const diff = target - now
if (map.has(diff)) {
// 如果差值存在, 则证明找到
return [map.get(diff), i]
} else {
// 存入当前值
map.set(now, i)
}
}
// 没有答案, 返回失败值
return [-1, -1]
}
字母异位词分组(第49题medium)
题目描述
给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。 字母异位词 是由重新排列源单词的所有字母得到的一个新单词。
解题
原理: 将字符串排序后存入哈希, 排序后的字母异位词将相等
var groupAnagrams = function (strs) {
// 初始化哈希
const map = new Map()
for (let str of strs) {
// 将字符串排序, 使得字母异位词存在同一个键下
const sortStr = str.split('').sort().join('')
if (map.has(sortStr)) {
map.get(sortStr).push(str)
} else {
map.set(sortStr, [str])
}
}
// 返回结果
return [...map.values()]
}
最长连续序列(第128题medium)
题目描述
给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。
请你设计并实现时间复杂度为 O(n) 的算法解决此问题。
解题
原理: 将数组存入哈希, 对每个元素判断, 如果-1不存在则是连续序列的开始.
var longestConsecutive = function (nums) {
// 初始化哈希, 之所以使用Set, 是因为初始化数组到哈希, Set比较方便
const set = new Set(nums)
let maxLen = 0
for (let num of nums) {
// 关键判断, 如果它之前的数字不存在, 证明当前这个数字是一个潜在的最长连续序列的开始
if (!set.has(num - 1)) {
// 以当前数字开始的长度
let len = 1
// 相当于当前数字+1, +2, +3...存在, 可以求出当前数字开始的连续序列的长度
while (set.has(num + len)) {
len++
}
// 更新最长长度
maxLen = Math.max(maxLen, len)
}
}
// 返回结果
return maxLen
}