之后补充Python的
哈希表理论基础
首先什么是哈希表,哈希表(英文名字为Hash table,国内也有一些算法书籍翻译为散列表,大家看到这两个名称知道都是指hash table就可以了)。
哈希表是根据关键码的值而直接进行访问的数据结构。
牺牲空间换取了时间.
哈希法用到的数据结构:数组,set(集合),map
242.有效的字母异位词
题意:判断两个字符串是否由相同字母组成
哈希值小,范围小,范围可控就可以使用数组这个数据结构.
数值很大的时候使用set
key对应有value就是用map
为什么使用哈希法:遍历一个字符串中的字母,判断是否再另一个字符串中出现.(给你一个元素判断集合中是否出现就用Hash)
用什么数据结构:题中说明了都是小写a-z,26个字母,范围小使用数组.
关键码的值:某个字符串中的所有元素
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']++;}for(int i = 0; i < t.length(); i++){record[t.charAt(i)-'a']--;}for(int count: record){if(count != 0 ){return false;}}return true;下面是我根据视频讲解写的// int[] hash = new int[26];//先定义hash数组// if(s.length() != t.length()){// return false;// }else{// for(int i= 0; i< s.length(); i++){// hash[s.charAt(i)-'a'] ++;// }// for(int i = 0; i < t.length(); i++){// hash[t.charAt(i)-'a']--;// }// for(int i = 0; i<26; i++){// if(hash[i]!=0){// return false;// }// }// }// return true;}
}
349. 两个数组的交集
题意:给定两个数组,编写一个函数来计算它们的交集。
为什么使用哈希法:也就是遍历其中某个数组,查看其中的元素是否在另一个数组中出现过,就使用哈希法.
使用什么数据结构:如果没有表明数字范围,数字可以很大,就使用set.如果表明数字范围,数字范围这个是可控的,小的,使用数组更有效.
关键码的值:某个数组中的所有元素
/**
好好思考一下JAVA怎么使用hash set*/
class Solution {public int[] intersection(int[] nums1, int[] nums2) {//这个是Hash set的if(nums1==null || nums1.length==0||nums2==null||nums2.length==0){return new int[0];//其中任意一个为空,说明没有交集}Set<Integer> set1 = new HashSet<>();//这个就是建立Hash set,整体我感觉还是好理解的就是把其中一个数组Hash映射得到Hash Set,然后再遍历另一个数组查找判断得到的Hash set中是否存在这个数Set<Integer> resSet = new HashSet<>();//这个就是结果数组//遍历数组1,应该是往hash表中存数,我感觉是先经过了一次Hash映射for(int i : nums1){set1.add(i);//}//遍历数组2的过程中判断哈希表中是否存在该元素for (int i : nums2){if(set1.contains(i)){resSet.add(i);//存在就往结果set中添加元素}}//方法1将结果集合转换成数组return resSet.stream().mapToInt(x -> x).toArray();//转换成数组// //方法2:另外申请一个数组存放setRes中的元素,最后返回数组 // int[] arr = new int[resSet.size()];//初始化一个数组// int j = 0;// for( int i : resSet){// arr[j++] = i;// }// return arr;}}
/**
好好思考一下JAVA怎么使用hash set*/
class Solution {public int[] intersection(int[] nums1, int[] nums2) {//再看一下用数组的形式的int[] hash1 = new int[1002];int[] hash2 = new int[1002];for(int i : nums1)hash1[i]++;//只要这个数存在就可以for(int i : nums2)hash2[i]++;List<Integer> resList = new ArrayList<>();for(int i = 0; i< 1002; i++)if(hash1[i]>0 && hash2[i]>0)resList.add(i);int index = 0;int res[] = new int[resList.size()];for(int i : resList)res[index++] = i;return res;}}
202. 快乐数
为什么使用哈希法:注意无限循环,说明如果其中sum重复出现就陷入无限循环.我们保存sum(每个数位的平方的和),然后判断sum是否重复出现,也就是当前的sum是否在过去sum的集合中出现过,就使用哈希法.
使用什么数据结构:这个题的数字没有限制范围,使用set
关键码的值:sum(当前数所有数位的数字的平方的和)
class Solution {public boolean isHappy(int n) {//试试JAVASet<Integer> record = new HashSet<>();//这个就是存储平方和的while(n!=1 && !record.contains(n)){//不是1就继续循环,然后如果record中没有就说明还没有陷入到死循环record.add(n);//往hash表中添加这个和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;}
}
1. 两数之和
为什么使用哈希法:因为它是遍历数组中的值,查找当前值对应的满足条件的另一个值是否在之前遍历过的值的集合中.
为什么使用map:因为这个题目是要返回下标,除了找到符合条件的元素还需要下标,两个值所以使用map
map的作用:存储遍历过的元素
map中的key分别存放什么:key存放元素值,value存放下标
class Solution {public int[] twoSum(int[] nums, int target) {int[] res = new int[2];//存放两个下标if(nums==null || nums.length==0){return res;}Map<Integer, Integer> map = new HashMap<>();//这个存放遍历过的元素for(int i = 0; i < nums.length; i++){int temp = target - nums[i]; // 遍历当前元素,并在map中寻找是否有匹配的keyif(map.containsKey(temp)){res[1] = i;res[0] = map.get(temp);break;}map.put(nums[i], i); // 如果没找到匹配对,就把访问过的元素和下标加入到map中}return res;}
}
参考的题目、文章、视频
- https://programmercarl.com/%E5%93%88%E5%B8%8C%E8%A1%A8%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html#%E5%93%88%E5%B8%8C%E5%87%BD%E6%95%B0
- https://leetcode.cn/problems/valid-anagram/description/
- 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
- https://www.bilibili.com/video/BV1YG411p7BA/
- https://leetcode.cn/problems/intersection-of-two-arrays/description/
- 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
- https://www.bilibili.com/video/BV1ba411S7wu/
- https://leetcode.cn/problems/happy-number/description/
- https://programmercarl.com/0202.%E5%BF%AB%E4%B9%90%E6%95%B0.html
- https://leetcode.cn/problems/two-sum/
- https://programmercarl.com/0001.%E4%B8%A4%E6%95%B0%E4%B9%8B%E5%92%8C.html#%E7%AE%97%E6%B3%95%E5%85%AC%E5%BC%80%E8%AF%BE
- https://www.bilibili.com/video/BV1aT41177mK/