哈希法
什么情况下适合用哈希法?
给一个元素,判断这个元素是否在集合中
哈希法常用的数据结构有:数组、set、map,怎么区分使用场景?
数组:集合长度不大
set:集合需要去重
map:需要存储两个变量
有效的字母异位词
leetcode链接:leetcode.cn/problems/va…
自己AC了,但是思路比较麻烦,不推荐,学习下哈希法
这道题目使用数组数据结构,因为英文字母只有26种,可以枚举出来,长度不大
一个比较取巧的点是,要让a在数组中对应下标0,那么需要减去一个a的ASCII码
第一次遍历s字符串,将s中字母出现的次数添加到哈希表中
第二次遍历t字符串,将t中字母出现的次数从哈希表中删除
第三次遍历哈希表,如果是有效的字母异位词,那么所有元素都是0
var isAnagram = function(s, t) {
const hashMap = new Array(26).fill(0);
const offset = "a".charCodeAt(0);
// 要注意,在JavaScript中两个字符串不能相减,会返回NaN
for (let i = 0; i < s.length; i++) {
hashMap[s.charAt(i).charCodeAt(0) - offset]++;
}
for (let i = 0; i < t.length; i++) {
hashMap[t.charAt(i).charCodeAt(0) - offset]--;
}
for (let i = 0; i < hashMap.length; i++) {
if (hashMap[i] !== 0) {
return false;
}
}
return true;
};
两个数组的交集
leetcode链接:leetcode.cn/problems/in…
怎么判断两个数组有交集,那肯定是数组1的某个元素出现在数组2中,那就可以使用哈希法
这道题目使用set数据结构,我使用了两个set数据结构的变量AC的,其实可以只使用一个
var intersection = function(nums1, nums2) {
// JavaScript中set会自动去重
let set = new Set(nums1);
let result = new Set();
// 查找nums[i]元素是否在set集合中
for (let i = 0; i < nums2.length; i++) {
if (set.has(nums2[i])) {
result.add(nums2[i]);
}
}
return Array.from(result);
};
快乐数
leetcode链接:leetcode.cn/problems/ha…
哈希表保存最新数字,不是快乐数会成环,在这个提示下AC了
题目中说了,不是快乐数无限循环,说明求和的过程中,和会重复出现(破题的关键)
var isHappy = function(n) {
let map = {};
while (map[n] !== 2) {
// 把数字转为字符串方便处理
let str = String(n);
let newNum = 0;
// 求和
for (let i = 0; i < str.length; i++) {
newNum += Math.pow(Number(str.charAt(i)), 2);
}
if (newNum === 1) return true;
// 新数字不等于1就存储在哈希表里面
if (map[n]) {
map[n] += 1;
} else {
map[n] = 1;
}
// n变成新的数字,继续求和
n = newNum;
}
return false;
};
学习下使用set数据结构的方法
var isHappy = function(n) {
let set = new Set();
while (n !== 1 && !set.has(n)) {
// 求和
let str = String(n);
let newNum = 0;
for (let i = 0; i < str.length; i++) {
newNum += Math.pow(Number(str.charAt(i)), 2);
}
set.add(n);
n = newNum;
}
return n === 1;
};
两数之和
leetcode链接:leetcode.cn/problems/tw…
为什么可以使用哈希法?
以 nums = [2,7,11,15], target = 9 举例
对于nums的第一个元素2,如果想要找到另外一个元素,使得两个元素相加等于target,target - 2 = 7,意味着7这个元素必须出现在nums集合中,符合使用哈希法的情况
为什么使用map数据结构?并且key是元素,value是下标
需要知道一个元素是否出现过,同时还需要知道这个元素对应的下标,那就需要存储两个变量,使用map
我们要查找的是一个元素是否出现过,那么应该把元素作为key
var twoSum = function(nums, target) {
let hash = {};
for (let i = 0; i < nums.length; i++) {
if (hash[target - nums[i]] !== undefined) {
return [i, hash[target - nums[i]]];
} else {
hash[nums[i]] = i;
}
}
return [];
};