文章目录
- 哈希表理论基础
- 哈希碰撞: 拉链法和线性探测法
- 线性探测法
- Leetcode242.有效的字母异位词
- 题目链接
- 思路
- AC代码
- Leetcode349. 两个数组的交集
- 题目链接
- 思路
- AC代码
- Leetcode 1. 两数之和
- 题目链接
- 思路与难点
- AC代码
- 收获
- 今日收获
哈希表理论基础
哈希函数如下图所示,通过hashCode把名字转化为数值,一般hashcode是通过特定编码方式,可以将其他数据格式转化为不同的数值,这样就把学生名字映射为哈希表上的索引数字了。
哈希碰撞: 拉链法和线性探测法
其实拉链法就是要选择适当的哈希表的大小,这样既不会因为数组空值而浪费大量内存,也不会因为链表太长而在查找上浪费太多时间。
线性探测法
使用线性探测法,一定要保证tableSize大于dataSize。 我们需要依靠哈希表中的空位来解决碰撞问题。
Leetcode242.有效的字母异位词
题目链接
思路
字母异位词是指 两个字符串,字符相同但位置不同。
本题主要是通过数组来完成的,创建一个存放26个字符的record数组
通过循环遍历 三次循环
- 第一次 是将字符串中出现的字符在record数组中都标记下来
- 第二次 则是将标记的字符次数都减去
- 第三次 进行判断 只有0是正确答案 不然return false 。
AC代码
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 j=0; j<t.length();j++)
{
record[t.charAt(j)-'a']--;
}
for(int count:record)
{
if(count!=0)
{
return false;
}
}
return true;
}
}
Leetcode349. 两个数组的交集
题目链接
思路
这道题我们用set来解决,因为相对于数组,哈希值比较少、特别分散、跨度非常大,使用数组就造成空间的极大浪费。
创建用来存储nums1中出现的字符 Set<Integer> set1
、创建用于存储 判断两个数组交集的集合
for(int i:nums2)
{
if(set1.contains(i))
{
resSet.add(i);
}
}
最后一步 ,将集合转换成数组 return resSet.stream().mapToInt(x->x).toArray();
AC代码
public int[] intersection(int[] nums1, int[] nums2) {
//1合理性判断
if (nums1==null|| nums1.length ==0 || nums2== null|| nums2.length==0)
{
return new int[0];
}
//2建立两个set
Set <Integer> set1 =new HashSet<>();
Set <Integer> resSet= new HashSet<>();
//for循环 将 for(int i: nums1) set1.add(i)
for(int i:nums1)
{
set1.add(i);
}
// 3for循环 将 if(set1.contains(i)) res.add(i)
for(int i:nums2)
{
if(set1.contains(i))
{
resSet.add(i);
}
}
//4 转化成 数组
return resSet.stream().mapToInt(x->x).toArray();
}
Leetcode 1. 两数之和
题目链接
思路与难点
- 难点: 如何使用map进行解答
使用数组和set来做哈希法的局限。- 数组的大小是受限制的,而且如果元素很少,而哈希值太大会造成内存空间的浪费。
- set是一个集合,里面放的元素只能是一个key
- 思路:
而两数之和这道题目,不仅要判断y是否存在而且还要记录y的下标位置,因为要返回x 和 y的下标。所以set 也不能用。
此时就要选择另一种数据结构:map ,map是一种key value的存储结构,可以用key保存数值,用value在保存数值所在的下标。
map是用来存放遍历过的元素, 每次遍历一个元素 都需要与target进行比较 形成一个temp如何出现在了map里我们就将res数组的0和1 put出来,
AC代码
class Solution {
public int[] twoSum(int[] nums, int target) {
int res[]=new int[2];
//合理性判断
if(res ==null|| res.length ==0)
{
return res;
}
// 生成一个HashMap
Map <Integer,Integer> map = new HashMap<>();
for(int i=0 ;i<nums.length;i++)
{
//生成一个temp 利用来进行转换
int temp =target-nums[i];
if (map.containsKey(temp)) //containsKey k必须大写
{
res[1]=i; //
res[0]=map.get(temp); //
break;
}
//如果前面并没有遍历到就将map.put key 和value 放进去
map.put(nums[i],i);
//return res
}
return res;
}
}
收获
- map用来做什么
map目的用来存放我们访问过的元素,因为遍历数组的时候,需要记录我们之前遍历过哪些元素和对应的下表,这样才能找到与当前元素相匹配的(也就是相加等于target)
- map中key和value分别表示什么
判断元素是否出现,这个元素就要作为key,所以数组中的元素作为key,有key对应的就是value,value用来存下标。
map中的存储结构为 {key:数据元素,value:数组元素对应的下表}。
今日收获
沉于其中,勤于手,无他