哈希表理论基础
文档讲解:代码随想录 (programmercarl.com)
242.有效的字母异位词
题目链接:242. 有效的字母异位词 - 力扣(LeetCode)
文档讲解:代码随想录 (programmercarl.com)
视频讲解:学透哈希表,数组使用有技巧!Leetcode:242.有效的字母异位词_哔哩哔哩_bilibili
解题思路:
class Solution {
public boolean isAnagram(String s, String t) {
int[] record = new int[26];
//创建一个用于记录一个字母出现了多少次的数组
for (int i = 0; i < s.length(); i++) {
record[s.charAt(i) - 'a']++;
}
//遍历s字符串,用record数组记录每个字母出现了多少次
for (int i = 0; i < t.length(); i++) {
record[t.charAt(i) - 'a']--;
}
//遍历s字符串,用record数组对照s和t字符串中每个字母出现的次数是否一致
for (int i : record) {
if (i != 0) {
return false;
}
}
//遍历数组record来判断两个字符串是否是字母异位词
return true;
}
}
时间复杂度:O(n)
该题总结:从今天开始转战java,c语言不太好实现哈希表里的set和map,正好以后也想深学java,以后就写java的代码了,这道题还好,用的是哈希数组,挺好理解的,但java方法用的不太熟练,需要多做题。
349. 两个数组的交集
题目链接:349. 两个数组的交集 - 力扣(LeetCode)
文档讲解:代码随想录 (programmercarl.com)
视频讲解:学透哈希表,set使用有技巧!Leetcode:349. 两个数组的交集_哔哩哔哩_bilibili
解题思路:
//set解法
class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
if (nums1 == null || nums2 == null) {
return new int[0];
}
//若数组1或2为空则直接返回一个空数组
Set<Integer> set1 = new HashSet<>();
Set<Integer> resset = new HashSet<>();
//创建两个HashSet
for (int i : nums1) {
set1.add(i);
}
//遍历数组1,将数组1的每个数添加到HashSet中
for (int i : nums2) {
if (set1.contains(i)) {
resset.add(i);
}
}
//遍历数组2,如果数组2的第i个数在set1中存在,就将其储存到resset这个哈希表中
return resset.stream().mapToInt(x -> x).toArray();
//将哈希表转化为数组
}
}
//数组解法
class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
int[] hash1 = new int[1001];
int[] hash2 = new int[1001];
//创建两个hash数组
for (int i : nums1) {
hash1[i]++;
}
for (int i : nums2) {
hash2[i]++;
}
//用两个hash数组分别记录两个数组里每个数出现的次数
List<Integer> reslist = new ArrayList<>();
//创建一个列表,相比于直接创建数组能节省空间
for (int i = 0; i < 1001; i++) {
if (hash1[i] != 0 && hash2[i] != 0) {
reslist.add(i);
}
}
//两个hash数组里都有一个数则将其添加到列表中
int index = 0;
int res[] = new int[reslist.size()];
for (int i : reslist) {
res[index++] = i;
}
//把列表里的数导入到数组里
return res;
}
}
时间复杂度:O(n)
该题总结:由于第一次接触java,这种set的声明方法第一次见到,不太熟练,对着答案写的很多,以后二刷的话希望能靠自己解决问题。
第202题. 快乐数
题目链接:202. 快乐数 - 力扣(LeetCode)
文档讲解:代码随想录 (programmercarl.com)
解题思路:
class Solution {
public boolean isHappy(int n) {
Set<Integer> tmp = new HashSet<>();
//定义一个HashSet
while (n != 1 && !tmp.contains(n)) {
//判断本次循环n是否为1以及tmp里是否存在n
tmp.add(n);
n = sum(n);
}
return n == 1;
//判断n是否为快乐数
}
private int sum(int n) {
int sum = 0;
while (n != 0) {
sum += Math.pow(n % 10, 2);
n /= 10;
}
//计算新的n按照快乐数算法的和
return sum;
}
}
时间复杂度:O(logn)
该题总结:这个快乐数的算法还挺不好想的,光看答案就想了好久每一步是怎么做出来的,主要是每次把新计算出来的数赋给n那里有点不好理解,不过想明白了以后也就没那么难了。
1. 两数之和
文档讲解: 代码随想录 (programmercarl.com)
视频讲解: 梦开始的地方,Leetcode:1.两数之和,学透哈希表,map使用有技巧!_哔哩哔哩_bilibili
解题思路:
class Solution {
public int[] twoSum(int[] nums, int target) {
int[] result = new int[2];
if (nums == null) {
return result;
}
//若数组为空则直接返回result
Map<Integer,Integer> hashmap = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
int tmp = target - nums[i];
if (hashmap.containsKey(tmp)) {
result[0] = hashmap.get(tmp);
result[1] = i;
break;
}
//找到匹配对则返回result数组
hashmap.put(nums[i], i);
//未找到匹配对就把当前的数和下标加入到map中
}
return result;
}
}
时间复杂度:O(n)
该题总结:这道题关键在于四点:
- 为什么会想到用哈希表
- 哈希表为什么用map
- 本题map是用来存什么的
- map中的key和value用来存什么的
这四点想清楚了这题也就不难做了,主要还是要熟练java各种代码的实现。