主题:哈希表
哈希表基础复盘
刷题:
242.有效的字母异位词
图文讲解代码随想录 (programmercarl.com)https://programmercarl.com/0242.%E6%9C%89%E6%95%88%E7%9A%84%E5%AD%97%E6%AF%8D%E5%BC%82%E4%BD%8D%E8%AF%8D.html#%E7%AE%97%E6%B3%95%E5%85%AC%E5%BC%80%E8%AF%BE视频讲解学透哈希表,数组使用有技巧!Leetcode:242.有效的字母异位词_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1YG411p7BA/题目及个人题解
//方法一:哈希表 采用数组
public boolean isAnagram(String s, String t) {
//思路:创建一个26长度的数组表示英文字母,对进行s统计次数,然后与t比较--
int[] res=new int[26];
int length=s.length();
for(int i=0;i<length;i++){
res[s.charAt(i)-'a']++;
}
for (int j=0;j<t.length();j++){
res[t.charAt(j)-'a']--;
}
for(int count:res){
if(count!=0){
return false;
}
}
return true;
}
//方法二:暴力 双层for循环 不推荐 比较简单,偷个懒不写啦
个人总结
这道题很好的锻炼了哈希表的应用,难度不大。需要注意的是,在使用哈希表中我们可能涉及到数组,set,list,map这些数据结构,要掌握对应数据结构的常用方法
349. 两个数组的交集
图文讲解代码随想录 (programmercarl.com)https://programmercarl.com/0349.%E4%B8%A4%E4%B8%AA%E6%95%B0%E7%BB%84%E7%9A%84%E4%BA%A4%E9%9B%86.html#%E7%AE%97%E6%B3%95%E5%85%AC%E5%BC%80%E8%AF%BE视频讲解学透哈希表,set使用有技巧!Leetcode:349. 两个数组的交集_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1ba411S7wu/
题目及个人题解
//方法一:思路是先采用set集合去重,再找交集
public int[] intersection(int[] nums1, int[] nums2) {
Set<Integer> first=new HashSet<>();
for(int num:nums1){
first.add(num);
}
Set<Integer> second=new HashSet<>();
for(int num:nums2){
//在这一步进行交集判断,相交放入
if(first.contains(num)){
second.add(num);
}
}
//可以优化为for循环
//如果数据在1万以内的话,for循环效率高于foreach和stream;
// 如果数据量在10万的时候,stream效率最高,
// 其次是foreach,最后是for。
// 另外需要注意的是如果数据达到100万的话,parallelStream异步并行处理效率最高,高于foreach和for。
//int[] res=new int [second.size()];
//int j=0;
//for(int num::second){
// res[j++]=num;
//}
//return res;
return second.stream().mapToInt(Integer::valueOf).toArray();
}
//方法二:采用数组,因为数据量被限制,但不推荐,实现简单,偷个懒不写啦
个人总结
这道题中涉及到set的使用,set会对数据进行去重,通过去重后的数据,我们可以找到交集,放入对应set中。有一个注意的点,就是优化方面,数据量小的情况下for循环效率高于stream。
202. 快乐数
public boolean isHappy(int n) {
//思路:如果是快乐数,那就意味着不会出现重复,也就是循环;反之,非快乐数,就会出现重复的结果
Set<Integer> set=new HashSet<>();
//对下面这部分代码进行简洁优化
//int k=n;
//while(1>0){
// int a=reInt(k);
//if(a==1){
// return true;
// }
//if(set.contains(a)){
// return false;
//}else{
// set.add(a);
//k=a;
//}
// }
while(n!=1&&!set.contains(n)){
set.add(n);
n=reInt(n);
}
return n==1;
}
public static int reInt(int target){
int sum=0;
while (target/10!=0){
int k=target%10;
sum+=k*k;
target/=10;
}
sum+=target*target;
return sum;
}
个人总结
这道题的核心在于找到是否循环,如果过程中出现了相同结果,则会议桌循环下去。我们可以判断每次结果是否在set中,在的话说明会循环返回false,反之将每次结果放入到set中,直到结果==1。
1.两数相加
视频讲解梦开始的地方,Leetcode:1.两数之和,学透哈希表,map使用有技巧!_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1aT41177mK/
题目及个人题解
public int[] twoSum(int[] nums, int target) {
int[] res=new int [2];
if(nums==null||nums.length==0){
return res;
}
//key存放数值 value存放索引
//思路是 先判断map中是否含有目标值,没有的话就可以将当前数据加入到map,而不是一开始直接扫描所有数据到map中
//为什么这么做呢?是因为可能有重复数值的出现,如果数组中有两个3,target=6,直接扫描的话map中的第一个3会被后一个覆盖掉
Map<Integer,Integer> hashMap=new HashMap<>();
for(int i=0;i< nums.length;i++){
if(hashMap.containsKey(target-nums[i])){
res[0]=i;
res[1]=hashMap.get(target-nums[i]);
break;
}else{
hashMap.put(nums[i],i);
}
}
return res;
}
个人总结
两数相加采用了map数据结构,其中containsKey(),put()函数需要掌握。
整体算法中没有一开始就将数据全部扫描到map中,而是先判断map中有无我们想要的值,无的话,将当前值放入map,反之返回对应数据。为什么怎么做呢?
举个例子 nums = [3,3], target = 6 如果我们先扫描会出现第一个3的索引会被第二个3覆盖掉。
个人鸡汤
一具体就深刻。