#day06 哈希表部分
力扣[242. 有效的字母异位词]
链接:https://leetcode.cn/problems/valid-anagram/
问题描述
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。
代码实现
class Solution {
public boolean isAnagram(String s, String t) {
//设置一个一维的数组,一共26个字母,来存储分别从a - z所有的字母出现的次数
int[] record = new int[26];
//开始遍历第一个字符串,记录字符串中每一个字母出现的次数
for(int i = 0; i < s.length();i++){
//record['a' - 'a'] = record[0]
//record['b' - 'a'] = record[1]
//这样就可以把每一个字母次数按照顺序存储在数组对应位置上
record[s.charAt(i) - 'a']++;
//完成记录s字符串中每一个字母出现的次数
}
for(int j = 0; j < t.length();j++){
record[t.charAt(j) - 'a']--;
//s中字符串 - t中的每个出现的次数
}
for(int i = 0; i < 26;i++){
if(record[i] != 0){
return false;
}
}
return true;
}
}
注意点
- 查找相同元素等操作一定想到hash数组
- 本题中因为字符串中的元素都是从a - z中的元素,在ASCII码中都是连续的,所以天然存在一个连续的哈希数组来分别对应每一个元素进行计数
力扣 [349. 两个数组的交集]
链接:https://leetcode.cn/problems/intersection-of-two-arrays/
问题描述
给定两个数组 nums1
和 nums2
,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。
代码实现
class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
HashSet<Integer> record = new HashSet<>();
HashSet<Integer> ans = new HashSet<>();
//遍历nums1,并且去重,把不重合的元素提取出来
for(int i : nums1){
record.add(i);
}
//遍历nums2,看看nums2里面是否包含nums1的元素
for(int i : nums2){
if(record.contains(i)){
ans.add(i);
}
}
//将ans这个set转化成数组
return ans.stream().mapToInt(x -> x).toArray();
}
}
注意点
-
构造一个HashSet记录不重复的元素
-
注意第二步contains的主体是已经确定的链表
-
将链表转化成数组的方法为
List list = new ArrayList<>();
int[] array = list.stream().mapToInt(Integer::valueOf).toArray();
力扣[202. 快乐数]
链接:https://leetcode.cn/problems/happy-number/
问题描述
编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」 定义为:
对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
如果这个过程 结果为 1,那么这个数就是快乐数。
如果 n 是 快乐数 就返回 true ;不是,则返回 false 。
代码实现
class Solution {
public boolean isHappy(int n) {
//新建一个hashset来存储下一个数字各部分累加结果
//查询得知,不是快乐数,累加之后会出现一部分重复的数字
Set<Integer> record = new HashSet<>();
//n不等于1且n在hashSet中还没有出现循环,就可以继续查下一个数字
while(n != 1 && !record.contains(n)){
//在hashset中添加n这条记录
record.add(n);
//获取新一轮的n
n = getNextNumber(n);
}
//跳出循环,n=1返回true,如果n在hashset中出现过,且不等于1,返回false
return n == 1;
}
//创建一个方法来获取下一轮的n的数字
private int getNextNumber(int n){
//初始化sum
int sum = 0;
//提取n的各个位上的数值,采用一个循环来达成,每次取出最低位
while(n != 0){
int temp = n % 10;
sum += temp * temp;
n = n / 10;
}
return sum;
}
}
}
注意点
- 快乐数在不停的位置上sum求和后肯定会出现循环,出现循环且不是1就不是快乐数
- 建议百度搜一下100以内的快乐数,发现一下他们之间的规律。
力扣1. 两数之和
链接: https://leetcode.cn/problems/two-sum/
问题描述
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
#代码实现
class Solution {
public int[] twoSum(int[] nums, int target) {
//创建需要返回的数组
int[] result = new int[2];
//想清楚hashmap中key存储的是nums[i],value存储的是i
HashMap<Integer,Integer> map = new HashMap<>();
for(int i = 0;i < nums.length;i++){
int score = target - nums[i];
//如果hashmap中的key中遍历过需要的score
if(map.containsKey(score)){
//取出map中score所在的value,value存储的是下标
result[0] = map.get(score);
result[1] = i;
}
//如果不是,就将数组中的元素存储进map中
map.put(nums[i],i);
}
return result;
}
}
注意点
- 为什么会想到用哈希表
- 哈希表为什么用map
- 本题map是用来存什么的
- map中的key和value用来存什么的