哈希表可以用来快速判断一个元素是否出现集合里。常见的哈希表有三种形式:数组、set (集合)、map(映射)
本系列博文将通过一些力扣算法题目,边学习TypeScipt边实战算法,这篇将通过一些经典算法题熟悉TS语言哈希表的一些基本操作。(部分算法思想参考于程序员Carl:代码随想录)
一、哈希表的定义
哈希表(Hash Table),又称为散列表,是一种通过哈希函数组织数据,以支持快速插入和搜索的数据结构。哈希表的核心思想是通过一个哈希函数将输入的键值(Key)映射到一个地址,然后通过这个地址来访问存储的数据值(Value)。
1.1、集合set
定义:let storeSet: Set<number> = new Set();
判断是否包含:if(storeSet.has(n))
往集合中增加元素:storeSet.add(n)
删除某个元素:storeSet.delete(n)
清空set:storeSet.clear()
获取set的所有值:let values = set.values();
遍历set:
let values = set.values();
for (let value of values) {
console.log(value);
}
1.2、映射Map
定义:let myMap: Map<number, string> = new Map(); // key value结构
得到map的大小: myMap.size
增加map的元素:myMap.set(1, "和键1关联的值");
是否包含某个成员:myMap.has(key)
删除成员:myMap.delete(key)
获取map的所有value值:myMap.values()
获取map的所有key值:myMap.keys()
根据key,得出value:myMap.get(1)
根据value,得出key:使用遍历
let myMap: Map<number, string> = new Map();
myMap.set(1, "和键1关联的值");
myMap.set(2, "和键2关联的值");
myMap.set(3, "和键3关联的值");
console.log(myMap.values());
console.log(myMap.keys());
console.log(myMap.get(1));
二、快乐数
力扣链接:https://leetcode.cn/problems/happy-number/
2.1、题目描述
编写一个算法来判断一个数 n 是不是快乐数
「快乐数」 定义为:
对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
如果这个过程 结果为 1,那么这个数就是快乐数。
如果 n 是 快乐数 就返回 true
;不是,则返回 false
。
2.2、示例
2.3、题解
题目中说了会 无限循环,那么也就是说求和的过程中,sum会重复出现,于是我们就可以用上哈希表来判断这个sum是否重复出现,如果重复了就是return false, 否则一直找到sum为1为止。
要注意的是,ts的number类型是浮点数,做除10时要使用floor向下取整。
代码语言:javascript复制function isHappy(n: number): boolean {
let storeSet: Set<number> = new Set();
while(!storeSet.has(n) && n != 1){
storeSet.add(n);
let tmp: number = 0;
let numn: number = n;
while(numn != 0){
tmp = tmp (numn % 10) * (numn % 10);
numn = Math.floor(numn / 10);
}
n = tmp;
}
if(n == 1)
return true;
else
return false;
};
三、两数之和
力扣链接:https://leetcode.cn/problems/two-sum/
3.1、题目描述
给定一个整数数组 nums
和一个整数目标值 target
,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。 你可以按任意顺序返回答案。
3.2、示例
3.3、题解
用哈希map来存数字,map目的用来存放我们访问过的元素,因为遍历数组的时候,需要记录我们之前遍历过哪些元素和对应的下表,这样才能找到与当前元素相匹配的(也就是相加等于target) 比如2 3 5 6 9 8 target=7 遍历数组,存入2,存入3之前找一下是否有4,没有,然后存入5,存入5之前找一下是否有2,发现哈希map里有,则输出当前下标和value2的下标。
代码语言:javascript复制function twoSum(nums: number[], target: number): number[] {
let resMap: Map<number, number> = new Map();
let index: number = 0;
for(let i: number = 0; i < nums.length; i ){
let anoNum: number | undefined = resMap.get(target - nums[i]);
if(anoNum !== undefined){
return [i , anoNum];
}
resMap.set(nums[i], i); //key value结构来存放,key来存元素,value来存下标
}
return nums;
};
四、四数相加||
力扣链接:https://leetcode.cn/problems/4sum-ii/submissions/
4.1、题目描述
给你四个整数数组 nums1、nums2、nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足:
0 <= i, j, k, l < n nums1[i] nums2[j] nums3[k] nums4[l] == 0
4.2、示例
4.3、题解
因为题目只要求得到有多少组,并不要求输出每一组的详细情况,且不用考虑重复的情况,我们将其分成两组,算和就行了。 也就是先算A和B数组的和有多少种情况,且每种和出现了几次,然后再算C和D中的数组的和满足条件的情况,找到如果 0-(c d) 在map中出现过的话,就用count把map中key对应的value也就是出现次数统计出来。最后返回统计值 count 就可以了。
代码语言:javascript复制function fourSumCount(nums1: number[], nums2: number[], nums3: number[], nums4: number[]): number {
let myMap: Map<number, number> = new Map();
for(let i of nums1){
for(let j of nums2){
let sumTemp: number | undefined = myMap.get(i j);
myMap.set(i j,sumTemp? sumTemp 1 : 1);
}
}
let res: number = 0;
for(let i of nums3){
for(let j of nums4){
let sumTemp: number | undefined = myMap.get(0 - i - j)
if(sumTemp)
res = res myMap.get(0 - i - j);
}
}
return res;
};
最后