目录
前言:哈希表理论基础
文章讲解:代码随想录
概念:
哈希函数:通过某种方式,把值转化为索引。
哈希表:根据关键码的值而直接进行访问的数据结构。
哈希碰撞:通过哈希函数之后,有元素映射到同一个位置。
- 哈希碰撞的处理方法:
- 拉链法:当元素映射到同一个位置时,在相应的位置存储到链表中。
- 线性探测法:前提是要保证tableSize大于dataSize,当元素映射到同一个位置时,向下找有空的位置。
LeetCode 242.有效字母异位词
文章讲解:代码随想录
视频讲解:学透哈希表,数组使用有技巧!Leetcode:242.有效的字母异位词_哔哩哔哩_bilibili
力扣题目: LeetCode 242.有效字母异位词
题目分析:首先了解字母异位词的定义,我们可以有个初步的了解,如果是字母异位词,字符串s中的每个字符个数一定是与字符串t中的每个字符个数相等的。所以我们可以先把字符串s中每个字符出现的次数定义在一个以26个字符长度的数组当中。接着在看字符串t中的每个字符的个数如果是与字符串s中每个字符的个数相对应的话, 那么定义的数组当中的元素就会全部为0。
代码如下(Java):代码随想录
class Solution {
public boolean isAnagram(String s, String t) {
//定义一个长度位26的数组,每个位置代表一个字母
int[] record = new int[26];
//遍历字符串s,找到相对于的字母,并且每找到相对于的字母,就在字母的位置山加1
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']--;
}
//遍历数组,若数组中还有元素不为0
//就意味着两个字符串中的字符数量不匹配
for(int count : record){
if(count != 0){
return false;
}
}
return true;
}
}
总结:通过数组下标来模拟a~z,数组中的元素来模拟字母出现的次数,再根据题目的逻辑(字母异位词的定义)即可解决该题目。
LeetCode 349.两个数组的交集
文章讲解:代码随想录
视频讲解:学透哈希表,set使用有技巧!Leetcode:349. 两个数组的交集_哔哩哔哩_bilibili
力扣题目:力扣
题目分析:比较两个数组之间是否存在着连续相同的元素,输出结果要做去重处理但是顺序不做要求。
代码如下(Java):代码随想录
class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
if(nums1 == null || nums1.length == 0 || nums2 == null || nums2.length == 0){
return new int[0];
}
Set<Integer> set1 = new HashSet<>();
Set<Integer> resSet = new HashSet<>();
for(int i : nums1){
set1.add(i);
}
for(int i : nums2){
if(set1.contains(i)){
resSet.add(i);
}
}
// return resSet.stream().mapToInt(x -> x).toArray();
int[] arr = new int[resSet.size()];
int j = 0;
for(int i : resSet){
arr[j++] = i;
}
return arr;
}
}
总结:因为题目返回的结果要求是去重的,但是顺序不做要求。基于这个条件下,我们可以先把其中一个数组做去重的操作,然后比较另一个也去重的数组,若两个数组之间有重复的元素,则代表有相同交集且已经做了去重的操作。
LeetCode 202. 快乐数
文章讲解:代码随想录
力扣题目:LeetCode 202. 快乐数
题目分析:快乐数的定义很容易理解,根据定义结果最后为1即为快乐数,但如果不是快乐数,就会无限循环,那么在这个过程中程序如何才知道这不是一个快乐数,需要有一个东西来判定不是快乐数,否则一直死循环且不知道结果。
代码如下(Java):代码随想录
class Solution {
public boolean isHappy(int n) {
Set<Integer> record = new HashSet<>();
while(n != 1 && !record.contains(n)){
record.add(n);
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;
}
}
LeetCode 1.两数之和
文章讲解:代码随想录
视频讲解:梦开始的地方,Leetcode:1.两数之和,学透哈希表,map使用有技巧!_哔哩哔哩_bilibili
力扣题目:LeetCode 1.两数之和
题目分析:第一种方法可以是使用暴力解法,直接套两个for循环即可,时间复杂度为O(n²)。第二种使用哈希表来解决,当我们需要判断一个元素是否出现在集合当中的时候,就可以考虑哈希法。在哈希法中,我们又得考虑三中方法来实现哈希法,分别为:数组,set以及map。在这道题中,我们需要判断元素是否存在以及返回相对于的下标,需要两个条件,而此时map中的key对应判断元素是否存在,value对应返回的元素的下标,符合我们对该题目的要求。
暴力代码如下(Java):
class Solution {
public int[] twoSum(int[] nums, int target) {
int[] res = new int[2];
int start = 0;
int end = 1;
int sign = 0;
for(int i = 0; i < nums.length; i++){
for(int j = i + 1; j < nums.length; j++){
if(nums[i] + nums[j] == target){
res[start] = i;
res[end] = j;
sign = 1;
break;
}
}
if(sign == 1){
break;
}
}
return res;
}
}
map代码如下(Java):
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];
if(map.containsKey(temp)){
res[1] = i;
res[0] = map.get(temp);
break;
}
map.put(nums[i], i);
}
return res;
}
}