【力扣】哈希表专题
在跟随代码随想录刷题的过程中,完成哈希表部分的相关题目,所以在此进行一个小总结。
本篇笔记涉及的力扣题目如下:【可以使用Ctrl+F进行搜索~】
关于哈希表的一些小总结:
- 关于HashMap的相关操作:Java HashMap;常用的方法如:根据key获取value值--get();map中是否包含相应的key或者value--containsKey() / containsValue();获取map中的值,如果没有则取默认值getOrDefault();将对应的key-value键值对放入map中--put()等
- Java HashSet;set集合中不允许重复元素,常用的方法有将元素假如set中--add();set中是否包含相应的元素--contains()等。
- 数组本身就是一个hashtable,例如对字母做相应操作,可以取int[26]
题目:242. 有效的字母异位词
解题思路
- 依次遍历s和t,将s中出现的字符依次填入哈希表中,出现一次则加1;
- 将t中出现的字符依次从哈希表中删去,出现一次则减1;
- 最后判断哈希表中是否有小于0的元素,若小于0则返回false,否则返回true。
Java代码实现--数组
class Solution {
public boolean isAnagram(String s, String t) {
int len1 = s.length();
int len2 = t.length();
if(len1 != len2) {
return false;
}
int[] res = new int[26];
for(int i=0; i<len1; i++) {
res[s.charAt(i) - 'a']++;
}
for(int i=0; i<len2; i++) {
res[t.charAt(i) - 'a']--;
}
for(int i=0; i<26; i++) {
if(res[i] < 0) {
return false;
}
}
return true;
}
}
Java代码实现--hashMap
class Solution {
public boolean isAnagram(String s, String t) {
int len1 = s.length();
int len2 = t.length();
if(len1 != len2) {
return false;
}
HashMap<Character, Integer> hashmap = new HashMap<>();
for(int i=0; i<len1; i++) {
char c1 = s.charAt(i);
if(hashmap.containsKey(c1)) {
// hashMap中包含当前字符
hashmap.replace(c1, hashmap.get(c1)+1);
} else {
// hashMap中不包含当前字符
hashmap.put(c1, 1);
}
}
for(int j=0; j<len2; j++) {
char c2 = t.charAt(j);
if(hashmap.containsKey(c2)) {
hashmap.replace(c2, hashmap.get(c2)-1);
if(hashmap.get(c2) < 0) {
return false;
}
} else {
return false;
}
}
return true;
}
}
参考资料:
题目:349. 两个数组的交集
解题思路:
- 将num1中每一个元素放入hash表中,依次比较nums2中每个元素是否存在于hash表中,若存在则将该元素写入res数组中,并将hash表中该元素的个数置为0(不输出重复元素),最后返回res即可。
- hash表大小:设置为1000,0 <= nums1[i], nums2[i] <= 1000
- 将hash表中该元素的个数置为0:表示该元素不存在于hash表中 / 已经输出无需再重复输出
- resultIndex表示返回数组的数组大小,在申请时,申请了lessSize个空间,在实际应用时不存在这么多元素。
解题思路
- 使用HashMap,将nums1中每个元素放入HashMap中;
- 设置一个ArrayList为res,用于记录结果
- 遍历nums2中的元素,如果该元素存在于map中,则说明该元素是nums1以及num2中的共同元素,将该值放入res中;如果已将该值放入res中,那么将map中的value值改为0,说明结果中已存在该值;遍历过程中,如果再次遇到当前值,那么就跳过该值【去重操作】。
Java代码实现
class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
HashMap<Integer, Integer> map = new HashMap<>();
ArrayList<Integer> res = new ArrayList<>();
int len1 = nums1.length;
int len2 = nums2.length;
// 遍历nums1,将nums1中的每个元素依次放入map中
for(int i=0; i<len1; i++) {
map.put(nums1[i], map.getOrDefault(map.get(nums1[i]), 1));
}
// 遍历nums2,如果nums2中的元素已经在map中,说明该元素是重复元素,将该值取出;
// 同时将value值赋值为0【去重操作】,当在nums2中再次遍历到值相同的元素,不对其进行操作
for(int i=0; i<len2; i++) {
if(map.get(nums2[i]) != null && map.get(nums2[i]) != 0) {
res.add(nums2[i]);
map.replace(nums2[i], 0);
}
}
// resArray用于返回结果,需要将ArrayList转化为int[]类型进行返回
int[] resArray = new int[res.size()];
for(int i=0; i<res.size(); i++) {
resArray[i] = res.get(i);
}
// res.toArray(resArray);
return resArray;
}
}
参考:349. 两个数组的交集
题目:202. 快乐数
解题思路
- 解题重点:该数可能循环
- 判断一个数是否是快乐数,是--》变为1;不是--》无限循环
- 使用Set用于记录结果,每次进行循环判断时,提前进行判断,如果该数出现在Set中,说明即将出现了循环
Java代码实现
class Solution {
public boolean isHappy(int n) {
Set<Integer> set = new HashSet<>();
while(n!=1 && !set.contains(n)) {
set.add(n);
n = getNextNum(n);
}
return n == 1;
}
public int getNextNum(int n) {
int res = 0;
while(n!=0) {
int temp = n % 10;
res += temp*temp;
n = n / 10;
}
return res;
}
}
参考资料:
题目:1. 两数之和
解题思路:
- 方法一:暴力解法
- 使用两次for循环,依次遍历整个数组
- 若计算结果符合要求,则返回相对应的数组下标
- 方法二:使用map
- 依次遍历整个数组,将遍历后的结果均写入map中,map用于记录key和value值。
- 在遍历的同时,依次查找map中是否有元素符合其值等于target-nums[i],若符合则返回该下标即可
- 若不符合,则将该元素的key和value记录下来,再次寻找下一个
Java代码实现
class Solution {
public int[] twoSum(int[] nums, int target) {
HashMap<Integer, Integer> map = new HashMap<>();
int[] res = new int[2];
for(int i=0; i<nums.length; i++) {
if(map.containsKey(target-nums[i])){
res[0] = i;
res[1] = map.get(target-nums[i]);
break;
// return res;
}
// 注意:该语句需要放在上述if语句之后。
// 假如先放入map中,那么例二[3,2,4], target=6;将结果记录在res中时,会同时取两遍"3"
map.put(nums[i], i);
}
return res;
}
}
参考资料
题目: 454. 四数相加 II
思路
- 使用map记录两数之和以及其出现次数,例如[-2, -1, 1], [-1, 1, 2]中,0出现的次数为-2+2,-1+1, 1+(-1)等。
- 将四数分为两两一组,该问题即转化为先将两数相加放入map中,之后再将另外两数相加,在map中寻找其相反数是否出现。
Java代码实现
class Solution {
public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
int res = 0;
// 该题仅需记录当前结果的数量,不需要记录下整个数组下标,所以,key=i+j; value=count
HashMap<Integer, Integer> map = new HashMap<>();
int len = nums1.length;
for(int i : nums1) {
for(int j : nums2) {
int temp = i + j;
if(map.containsKey(temp)) {
map.put(temp, map.get(temp) + 1);
} else {
map.put(temp, 1);
}
}
}
for(int i : nums3) {
for(int j : nums4) {
int temp = i + j;
// 如果存在和前两数之和相反的数,那么结果加上-temp的个数
if(map.containsKey(-temp)) {
res += map.get(-temp);
}
}
}
return res;
}
}

浙公网安备 33010602011771号