题目:
242.有效的字母异位词 349. 两个数组的交集 202. 快乐数 1. 两数之和
学习内容:
哈希表理论基础
哈希表是根据关键码的值而直接进行访问的数据结构,表现为键值对。 一般哈希表用来判断一个元素是否出现在集合里。其实就是适合通过O(1)的时间复杂度直接查询指定元素。
下图是利用哈希函数由key求value的过程:
但是这也可能存在哈希碰撞的情况:
242.有效的字母异位词
这道题我们使用数组来解决问题,数组的值表示字母出现的频率,索引表示第1-26个字母。
class Solution {
public boolean isAnagram(String s, String t) {
int[] record = new int[26]; // 定义一个长度为26的数组,记录每一个字母出现的次数
// 字符串s录入频数
for (int i = 0; i < s.length(); i++) {
record[s.charAt(i) - 'a']++;
}
// 字符串t录入频数
for (int i = 0; i < t.length(); i++) {
record[t.charAt(i) - 'a']--;
}
// 遍历record,看是否有非0,有则返回false
for (int count:record) {
if (count != 0) {
return false;
}
}
return true;
}
}
时间复杂度:O(m+n)或O(n),两个循环
空间复杂度:O(1),因为record长度恒定。
349. 两个数组的交集
这道题的关键是,什么时候用set什么时候用数组。题目中需要输出的元素是不重复的,使用set。如果是size固定的输入,则可以考虑数组。
class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
Set<Integer> hashset_1 = new HashSet<>();
Set<Integer> hashset_res = new HashSet<>();
for (int i : nums1) {
hashset_1.add(i);
}
for (int i : nums2) {
if (hashset_1.contains(i)) {
hashset_res.add(i);
}
}
// 将hashset转为int[]
int[] res = new int[hashset_res.size()];
int j = 0;
for (int i : hashset_res) {
res[j++] = i;
}
return res;
}
}
时间复杂度:O(n)
空间复杂度:O(n),hashset_res是动态的
202.快乐数
这题有一个难点,就是不仅仅是要取一个n的各位的数,其次还要判断到底会不会陷入死循环。这时候需要存储所有的sum值,来判断是否有重复的,有就说明死循环了。
class Solution {
public boolean isHappy(int n) {
Set<Integer> hashset = new HashSet<>();
while (n != 1) {
int sum = 0;
while (n != 0) {
sum += (n % 10) * (n % 10);
n = n / 10;
}
if (!hashset.contains(sum)) {
hashset.add(sum);
} else {
return false;
}
n = sum;
}
return true;
}
}
1.两数之和
暴力法(略)。
使用hashmap。我们要查找的是元素是否出现过,所以元素对应key,下标对应输出的value。
class Solution {
public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> hashmap = new HashMap<>();
int[] res = new int[2];
for (int i = 0; i < nums.length; i++) {
int temp = target - nums[i];
if (hashmap.containsKey(temp)) {
res[0] = i;
res[1] = hashmap.get(temp);
break;
}
hashmap.put(nums[i], i);
}
return res;
}
}
学到了什么
- 哈希表(Hash table)三种常见的结构:数组,set(集合),map(映射)。
其中set存储的元素不可重复,map使用key-value存储,非常适合用key来搜索。 - 求set的大小:
HashSet.size();
判断是否含有某个元素:HashSet.contains(a);
添加和移除元素: HashSet.add();HashSet.remove();
通过set接口来声明变量:Set <Integer> hashset_1 = new HashSet<>();
降低代码的耦合性. - **当我们要判断一个元素是否出现在集合中时,要想到哈希法。**判断有无重复的用hashset。
- 对一个数字 取每一位,
n = n % 10; n = n / 10;
学习时间:
2024.3.11