一、哈希表理论基础
哈希表是根据关键码的值而直接进行访问的数据结构
哈希函数:通过特殊的编码方式把关键码转为可以映射到哈希表的索引
哈希碰撞:不同的关键码映射到同一个索引位置
拉链法: 当哈希函数得到的索引位置相同发生冲突,冲突的元素存储在链表中
拉链法就是要选择合适的哈希表大小,既不会因为空值而浪费空间,也不会因为链表太长使查找时间太长
线性探测法:保证哈希表长度大于数据长度
只要需要快速判断一个元素是否出现在集合里,就要考虑哈希法
二、有效的字母异位词
问题要点
字母异位词都是字母,可以把字母映射到数组的索引,统计字符串中字符出现的次数,然后判断另一个字符串是否满足要求时,遍历求减,最终数组中每个元素为0,即为字母异位词
/**
* @param {string} s
* @param {string} t
* @return {boolean}
*/
var isAnagram = function(s, t) {
if(s.length !== t.length) {
return false
}
let arr = new Array(26).fill(0)
let base = 'a'.charCodeAt()
for(let i of s) {
arr[i.charCodeAt() - base]++
}
for(let i of t) {
if(!arr[i.charCodeAt() - base]) {
return false
}
arr[i.charCodeAt() - base]--
}
return true
};
三、两个数组的交集
问题要点
hash表方法:通过Set存储数组元素,遍历另一个数组判断,最终的结果需要去重
双指针方法:先把两个数组排序,然后用两个指针分别指向数组的起点,如果相等,同时移动指针,如果不同,分别移动(小的移动)
哈希法
/**
* @param {number[]} nums1
* @param {number[]} nums2
* @return {number[]}
*/
var intersection = function(nums1, nums2) {
if(nums1.length < nums2.length) {
[nums1, nums2] = [nums2, nums1]
}
let set = new Set(nums1)
let res = new Set()
for(let item of nums2) {
if(set.has(item)) {
res.add(item)
}
}
return Array.from(res)
};
双指针法
/**
* @param {number[]} nums1
* @param {number[]} nums2
* @return {number[]}
*/
var intersection = function(nums1, nums2) {
nums1.sort((x, y) => x - y)
nums2.sort((x, y) => x - y)
let index1 = 0
let index2 = 0
let res = new Set()
while(index1 < nums1.length && index2 < nums2.length) {
if(nums1[index1] === nums2[index2]) {
res.add(nums1[index1])
index1++
index2++
} else if(nums1[index1] < nums2[index2]) {
index1++
} else {
index2++
}
}
return Array.from(res)
};
四、快乐数
问题要点
需要一个哈希表来存储计算结果,如果已经出现过,则证明不是快乐数,求和可以使用如下两种,reduce求和或者获取余数求和
/**
* @param {number} n
* @return {boolean}
*/
var isHappy = function(n) {
let set = new Set()
while( n !== 1 && !set.has(n)) {
set.add(n)
n = getSum(n)
}
return n === 1
};
function getSum(n) {
// let sum = 0
// while(n) {
// sum += (n % 10) ** 2
// n = Math.floor(n / 10)
// }
// return sum
return String(n).split('').reduce((sum, cur) => {
return sum + cur ** 2
}, 0)
}
五、两数之和
问题要点
哈希表法:使用哈希表记录数组元素,如果能够找到与target的差值,则直接返回结果,否则添加该元素进入哈希表
/**
* 哈希表方法
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
var twoSum = function(nums, target) {
let map = new Map();
for(let i = 0; i < nums.length; i++) {
if(map.has(target - nums[i])) {
return [map.get(target - nums[i]), i]
}
map.set(nums[i], i)
}
return [-1, -1]
};