代码随想录算法训练营第六天|哈希表242、349、202、1
文章目录
LeetCode 242.有效的字母异位词
解题思路:建立一个hash[26],存放s中各字母出现的频数,之后减去t中各字母出现的频数;
hash[s.charAt(i) - ‘a’]++;// 并不需要记住字符a的ASCII,只要求出一个相对数值就可以了
遇到的问题:
charAt(i):从字符串中取字符的函数
s.length():取字符串长度
代码如下:
class Solution {
public boolean isAnagram(String s, String t) {
int[] hash = new int[26];
for(int i = 0;i < 26;i++){
hash[i] = 0;
}
for(int i = 0;i < s.length();i++){
hash[s.charAt(i) - 'a']++;// 并不需要记住字符a的ASCII,只要求出一个相对数值就可以了
}
for(int i = 0;i < t.length();i++){
hash[t.charAt(i) - 'a']--;
}
for(int i = 0;i < 26;i++){
if(hash[i] != 0){
return false;
}
}
return true;
}
}
LeetCode 349.两个数组的交集
解题思路:要注意,使用数组来做哈希的题目,是因为题目都限制了数值的大小。 而这道题目没有限制数值的大小,就无法使用数组来做哈希表了。而且如果哈希值比较少、特别分散、跨度非常大,使用数组就造成空间的极大浪费。
Java中的set哈希表的创建方法如下:
Set<Integer> set1 = new HashSet<>();
给定一个数据可以使用 .add() 函数向哈希表中存储元素。判断哈希表是否包含某个元素可以使用 .contains(key) 。与之前的数组哈希表相比, set哈希更适用于数据没有指定范围的题目,而且set哈希主要用于快速判断某个元素是否存在于哈希表中
难点:
对于
for(int i : nums1){
set1.add(i);
}
首先,nums是一个数组,里面放的是int类型的数据,然后定义了一个int类型的变量num,每循环一次,就从nums数组中取出一个数据来打印。
-
int :表示你要遍历的集合的类型
-
nums:表示你要遍历的集合的名
-
num:表示你每遍历集合中一个元素 便存储到该变量中,
然后在foreach语句的{}使用num变量;
//将结果集合转为数组
return resSet.stream().mapToInt(x -> x).toArray();
代码如下:
import java.util.Set;
import java.util.HashSet;
class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
if(nums1 == null || nums2 == null || nums1.length == 0 || nums2.length == 0){
return new int[0];
}
Set<Integer> set1 = new HashSet<>();
Set<Integer> resSet = new HashSet<>();
//遍历数组1
for(int i : nums1){
set1.add(i);
}
//遍历数组2
for(int i : nums2){
if(set1.contain(i)){
resSet.add(i);
}
}
//将结果集合转为数组
return resSet.stream().mapToInt(x -> x).toArray();
}
}
LeetCode 202.快乐数
解题思路:题目中说了会 无限循环,那么也就是说求和的过程中,sum会重复出现
当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法了。
遇到的问题:求和的过程,对取数值各个位上的单数操作不熟悉
代码如下:
import java.util.Set;
import java.util.HashSet;
class Solution {
public boolean isHappy(int n) {
Set<Integer> record = new HashSet<>();
while (n != 1 && !record.contains(n)) {//此处死循环也没有关系
record.add(n);
n = getNextNumber(n);
}
return n == 1;
}
private int getNextNumber(int n){
int res = 0;
while(n > 0){//当小数执行n = n / 10时,n为0
int temp = n % 10;
res += temp * temp;
n = n / 10;
}
return res;
}
}
LeetCode 1.两数之和
解题思路:在遍历数组的时候,只需要向map去查询是否有和目前遍历元素比配的数值,如果有,就找到的匹配对,如果没有,就把目前遍历的元素放进map中,因为map存放的就是我们访问过的元素。
遇到的问题:拿到num先看能不能用if(nums == null || nums.length == 0),以及map相关语句处理
代码如下:
class Solution {
public int[] twoSum(int[] nums, int target) {
int[] res = new int[2];
if(nums == null || nums.length == 0){
return res;
}
Map<Integer, Integer> map = new HashMap<>();
for(int i = 0;i < nums.length;i++){
int temp = target - nums[i]; // 遍历当前元素,并在map中寻找是否有匹配的key
if(map.containsKey(temp)){
res[1] = i;
res[0] = map.get(temp);
break;
}
map.put(nums[i], i); // 如果没找到匹配对,就把访问过的元素和下标加入到map中
}
return res;
}
}