哈希表| 242.有效的字母异位词 、349. 两个数组的交集 、 202. 快乐数 、 1. 两数之和
📋目录
✅ 242.有效的字母异位词
✅ 349.两个数组的交集
✅ 202.快乐数
✅ 1.两数之和
242.有效的字母异位词(数组哈希)
⏰ 1.解题思路
- 创建一个新数组,用来记录字符串中字符出现的次数---相当于将字符映射到数组也就是哈希表的索引下标上
- 遍历第一个字符串,将出现的字符次数记录+1,关键代码's.charCodeAt(i) - "a".charCodeAt(i)'
- 遍历第二个字符串,将出现的字符次数-1
- 最后判断数组中元素值是不是都为0,如果不是则返回false
💻 2.代码
/**
* @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); //新建数组,每个元素的值为0
let pivod = "a".charCodeAt(0); //97,不用特意去记ASCII,这里只需要相对位置,eg: "f".charCodeAt(0)=102,减去97,相对位置是5
for (let i = 0, n = s.length; i < n; i++) {
arr[s.charCodeAt(i) - pivod]++; //在arr[index]的数值上加1
arr[t.charCodeAt(i) - pivod]--;
}
return arr.every((i) => i === 0); //返回的是一个布尔值
};
🍯 3.知识点补充
🍊 快速判断一个元素是是否出现在集合中,就要想到用哈希法来解决问题。
🍒 常见的3种哈希表的数据结构,适用范围
-
- 数组:简单的hash表,哈希值小,范围可控
- set:数据结构大
- map:数据结构法,并且key有对应的value值
🍇 String.prototype.charCodeAt() 方法返回的 0 到 65535 之间的整数
eg: "a".charCodeAt(0) = 97 是它的ASCII码
🍓 Array.prototype.every() 方法返回的是一个布尔值,是测试一个数组内的所有元素是否都能通过指定函数的测试。
eg: arr.every((i) => i === 0) //测试的就是这个数组中是不是所有元素都是0
349.两个数的交集(set哈希)
⏰ 1.解题思路
- 先比较两个数组的大小,将长度较长的数组存到哈希表。
- 遍历短的数组,判断哈希表中是否存在长数组中。
💻 2.代码
/**
* @param {number[]} nums1
* @param {number[]} nums2
* @return {number[]}
*/
var intersection = function(nums1, nums2) {
//判断数组大小
if(nums1.length < nums2.length){
let _ = nums1;
nums1 = nums2;
nums2 = _;
}
const nums1Set = new Set();
//结果是数组中的每一个元素都是唯一的,所以也创建一个哈希表
const resSet = new Set();
for (let i = 0; i< nums2.length; i++){
nums1Set.has(nums2[i]) && resSet.add[nums2[i]]
}
return Array.from(resSet);
};
🍯 3.知识点补充
🍊 如果哈希值比较少、特别分散、跨度非常大,使用数组就造成空间的极大浪费!
🍒 Array.from() 方法 静态方法从可迭代或类数组对象创建一个新的浅拷贝的数组实例。
202.快乐数(set哈希)
⏰ 1.解题思路
- 抓住重点,最后结果就是,这个变成1或者重复出现,也就是题目中的无限循环。
- 哈希表中的每一个元素都是唯一的。
💻 2.代码
/**
* @param {number[]} nums1
/**
* @param {number} n
* @return {boolean}
*/
var getSum = function (n) {
//获取sum
let sum = 0;
while(n){
sum += (n % 10) ** 2 //取个位数,并且平方,累加
//取剩下的各个数,再进入循环,取个位数,直到最后一位数。
//最后一位数的取值[1,9],除10向下取整,都会等于0,此时就可以跳出循环。
n = Math.floor(n / 10)
}
return sum
}
var isHappy = function(n) {
const set = new Set();
while(n !== 1 && !set.has(n)){
set.add(n);
n = getSum(n);
}
return n === 1;
};
1.两数之和(map哈希)
⏰ 1.解题思路
- 创建一个map存放,已经访问过的数组。
- 遍历数组,向map去查询是否有和当前元素匹配的数值,如果有,就返回下标,没有就把当前遍历的元素放进map中。
💻 2.代码
/**
* @param {number[]} nums1
/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
var twoSum = function (nums, target) {
let map = new Map();
let resArr = [];
for (let i = 0; i < nums.length; i++) {
let index = map.get(target - nums[i]);
if (index !== undefined) {
resArr = [index, i];
}
map.set(nums[i], i); //将没有匹配到,但是已经遍历的元素存到map中
}
return resArr;
};
🍯 3.知识点补充
🍊 快速判断一个元素是是否出现在集合中,就要想到用哈希法来解决问题。
🍒 常见的3种哈希表的数据结构,适用范围(重新总结)
-
- 数组:简单的hash表,范围可控,哈希值太大会造成内存空间的浪费
- set:数据结构大,存放的元素只能是一个key。
- map:map是一种key value的存储结构,用key保存数值,用value保存数值所在的下标。