代码随想录算法训练营第六天|哈希表专题一
今日任务:
- 了解哈希表的理论基础
- leetcode 242 有效的字母异位词
- leetcode 349 两个数组的交集
- leetcode 202 快乐数
- leetcode 1 两数之和
哈希表理论基础
文章介绍:Hash表理论基础
leetcode 242 有效的字母异位词
题目链接:https://leetcode.cn/problems/valid-anagram/
题目详情:
思路
判断是否是字母异位词只需要判断两个字符串中的字符和字符个数是否一致,如果一致则返回true,反之返回false,那么我们可以借助数组或者HashMap来实现。
使用数组:开辟一个大小为26的数组,用来表示26个英文字符,遍历第一个串,每个对应的字符都+1,遍历第二个串,每个对应的字符都-1,这样最后如果数组全为0,说明两个字符串的字符和字符个数都一样。
使用HashMap: 与使用数组原理大致一致,遍历第一个串,将其存入到hashmap中,key为字符,value为字符个数,之后遍历第二个串,如果所第二个串中的某个字符是在hashmap中不存在的话,那么说明第一个串中是没有该字符,也就是说明不是字母异位词。如果存在就把对应的value做个-1操作,最后遍历这个hashmap,看看value是否存在不等于0的情况,如果不等于0的话,那么说明两个字符串中,该字符个数不等。
方法一:使用数组
class Solution {
public boolean isAnagram(String s, String t) {
//解题思路:首先开辟一个能够容纳26个字母的数组,从0-25代表a-z
//首先遍历s串,将里面的字符添加数组进去,遍历t串,将里面的字符移除出去
//如果s和t是字母异位词的话,最后数组最后全为0
int[] res = new int[26];
for(int i=0;i<s.length();i++){
char ch=s.charAt(i);
res[ch-'a']++;
}
for(int i=0;i<t.length();i++){
char ch=t.charAt(i);
res[ch-'a']--;
}
for(int i=0;i<res.length;i++){
if(res[i]!=0){
return false;
}
}
return true;
}
}
方法二:使用HashMap
class Solution {
public boolean isAnagram(String s, String t) {
HashMap<Character,Integer> hashMap =new HashMap<>();
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if (hashMap.containsKey(ch)) {
hashMap.put(ch, hashMap.get(ch) + 1);
} else {
hashMap.put(ch, 1);
}
}
for (int i = 0; i < t.length(); i++) {
char ch = t.charAt(i);
if (hashMap.containsKey(ch)) {
hashMap.put(ch, hashMap.get(ch) - 1);
} else {
return false;
}
}
Iterator<Character> iterator = hashMap.keySet().iterator();
while(iterator.hasNext()){
char ch=iterator.next();
if(hashMap.get(ch)!=0){
return false;
}
}
return true;
}
}
leetcode 349 两个数组的交集
题目链接:https://leetcode.cn/problems/intersection-of-two-arrays/
题目详情:
思路
因为结果不重复,所以可以考虑使用set返回结果,使用hashmap保存nums1中出现的数字,都只保留一遍,因为只要nums2中出现了一次就可以添加到set中了,如果nums2中出现了多次在set中也只会保留一份。
代码
class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
HashMap<Integer,Integer> map=new HashMap<>();
for(int i=0;i<nums1.length;i++){
map.put(nums1[i],0);
}
Set<Integer> set =new HashSet<>();
for(int i=0;i<nums2.length;i++){
if(map.containsKey(nums2[i])){
set.add(nums2[i]);
}
}
int[] res =new int[set.size()];
int index=0;
for(int i : set){
res[index++]=i;
}
return res;
}
}
leetcode 202 快乐数
题目链接:https://leetcode.cn/problems/happy-number/
题目详情:
思路
首先我们需要知道什么是快乐数,快乐数就是,每次把这个数的每个位置进行平方后相加起来,如果最后得到的结果为1,那么这个数就为快乐数。
那我们就需要一直进行循环判断,直到找到快乐数,但是有一种情况就是一定知道他不是快乐数,那么是什么情况呢?如果你平方后相加起来的数字,在之前已经出现过的话,那么这个数是不是会一直死循环。所以我们就需要每次把得到的数组存入一个hashMap中,每次获得新的数字之后就进行一次判断,如果这个数字不存在map中就存入map,继续拆分,知道==1时返回true,反之,如果存在在map中,那么就永远不可能得到1,无限循环,则返回false。
代码
class Solution {
public boolean isHappy(int n) {
HashMap<Integer,Integer> map =new HashMap<>();
while(true){
if(map.containsKey(n)){
return false;
}else{
map.put(n,1);
int sum=0;
while(n!=0){
int temp =n%10;
sum=sum+temp*temp;
n/=10;
}
if(sum==1) return true;
n=sum;
}
}
}
}
leetcode 1 两数之和
题目链接:https://leetcode.cn/problems/two-sum/
题目详情:
代码
class Solution {
public int[] twoSum(int[] nums, int target) {
//最后返回的结果数组
int[] res =new int[2];
//key用来存储数组元素,value用来存储元素对应的下标
HashMap<Integer,Integer> map =new HashMap<>();
for(int i=0;i<nums.length;i++){
//求两者的差值
int temp=target-nums[i];
//判断差值是否存在在map中,如果存在就直接返回两者的位置。
if(map.containsKey(temp)){
res[0]=i;
res[1]=map.get(temp);
return res;
}else{
//如果不存在就将该位置元素添加到map中
map.put(nums[i],i);
}
}
return res;
}
}