1. 有效的字母异位词
题目链接:242.有效的字母异位词
1.看到这道题目的思路是:判断两个字符串是否包含相同次数的字符,很容易就联想到用hash表来解决问题,遍历第一个字符串的时候把字符和字符出现的次数存放到hashmap中,然后遍历第二个字符串的时候去取,遇到相同字符次数就减一,如果key值不存在或者遍历完value不为0,就不是异位词
2.学习视频链接
3.写的过程中遍历第一个字符串的时候给key赋值value的时候,要先从map中取,要使用map.getOrDefault(c, 0) + 1,直接使用get()取的话,最开始map为空会出现空指针,第二次遍历的时候,只需要把key的value减一,然后判断value是否小于1
code
public boolean isAnagram(String s, String t) {
if (s.length() != t.length()) {
return false;
}
// 定义一个hashmap用于存放字符和字符出现的次数
HashMap<Character, Integer> map = new HashMap<>();
// 遍历第一个字符串将字符和出现的次数放到map中
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
map.put(c, map.getOrDefault(c,0) + 1);
}
// 遍历第二个字符串,出现相同字符,就将value减一
for (int i = 0; i < t.length(); i++) {
char c = t.charAt(i);
map.put(c, map.getOrDefault(c,0) - 1);
if (map.get(c) < 0) {
return false;
}
}
return true;
}
4.代码随想录中的解法使用的是数组,因为是都是小写字母的字符串,是固定长度而且连续的a-z,就可以直接使用数组来存放字符出现的次数,而数组的下标0-25对应的就是字符a-z
2.两个数组的交集
题目链接:349.两个数组的交集
1.看到题目时,有两种解题思路,一种是跟上一题一样使用数组,因为题目里给了限制0<= nums[i] <= 1000,就定义一个长度为10001的数组;第二种思路是遍历第一个数组使用set存放元素,再遍历第二个数组取出来相同的元素
2.学习视频链接
3.利用set集合元素不重复的属性,遍历第一个数组放进set集合,遍历第二遍使用contains方法找到相同元素,然后加入新的结果set集合,最后将set转成数组
code
public int[] intersection(int[] nums1, int[] nums2) {
HashSet<Integer> set = new HashSet();
HashSet<Integer> resultSet = new HashSet();
for (int i = 0; i < nums1.length; i++) {
set.add(nums1[i]);
}
for (int i = 0; i < nums2.length; i++) {
if (set.contains(nums2[i])) {
resultSet.add(nums2[i]);
}
}
return resultSet.stream().mapToInt(x->x).toArray();
}
3.快乐数
题目链接:202.快乐数
1.看到题目有点懵,没有思路不知道该怎么做
2.看了解析时候有些明白了,判断一个数是不是快乐数,再进行平方求和的过程中,最后会出现两种情况,一种是平方和等于1,是快乐数,另一种就是会陷入求和的循环,在求和过程中会出现相同的和,所以再循环求和的过程中除非和为1,不然就一直循环,然后把求到的和添加到set集合中,如果出现了set集合中已经出现过的和,那么就说明进入了求和循环,就不是快乐数返回false
code
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) {
int temp = n % 10;
res += temp * temp;
n = n / 10;
}
return res;
4.两数之和
题目链接:1.两数之和
1.写了好多遍的第一题,最熟的仍然是暴力解法,使用map解法的思路是:遍历数组将数组的元素作为key,元素对应的下标作为value存到map中,然后判断target和当前元素的差是否存在map如果存在,就返回当前数组元素下标和存在的value
2.学习视频
code
public int[] twoSum(int[] nums, int target) {
int[] res = new int[2];
// 定义一个map,key存放数组元素,value存放元素对应下标
HashMap<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
int temp = target - nums[i];
if (map.containsKey(temp)) {
res[1] = map.get(temp);
res[0] = i;
}
map.put(nums[i], i);
}
return res;
}
4.学习感悟:这道题目不难,但是以前都想不到用哈希表来求解,题目可以理解成判断target 与当前数组元素的差是否存在,一想到元素是否出现过,就联想到使用哈希表,题目要求返回符合条件的元素下标,可以想到这个哈希表不仅要存数组元素还要存下标,只有key-value的map符合。