哈希表1|242.有效的字母异位词|349.两个数组的交集 |202.快乐数 |1. 两数之和
一、哈希表理论基础
-
哈希表是根据关键码的值而直接进行访问的数据结构。
-
使用情况:一般哈希表都是用来快速判断一个元素是否出现集合里。 需要判断一个元素是否出现过的场景也应该第一时间想到哈希法 。哈希法是牺牲了空间换取了时间,因为我们要使用额外的数组,set或者是map来存放数据,才能实现快速的查找。
-
相关知识:哈希函数、哈希碰撞。 解决哈希碰撞的方法:拉链法、线性探测法。
-
三种常见的哈希结构:数组、set(集合)、map(映射)
二、242.有效的字母异位词
题目连接:242. 有效的字母异位词 - 力扣(LeetCode)
- 此题运用的哈希结构是数组,因为字母是a-z总共26个,用数组中0-26的位置表示a-z。用数组比较简单,数组记录s中每个字母出现的次数,如果和t中如果字母出现的次数相同的话,两个字符串就是有效的字母异位词。
- 这里s.charAt(i) - ‘a’ 就是该字母在哈希数组中对应的位置。
class Solution {
public boolean isAnagram(String s, String t) {
int[] hash = new int[26];
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 count : hash){
if(count != 0){
return false;
}
}
return true;
}
}
三、349.两个数组的交集
题目连接:349. 两个数组的交集 - 力扣(LeetCode)
- 这题和上题差不多,因为题目有说明nums[i] < 1000 , 故可以用哈希法中的数组结构解题。数组大小设为1001,hash数组各个位置代表0—1000的数是否在nums1里出现过,1表示出现过;0表示没出现过
- 流处理 ArrayList转int[]用 arrayList.stream().mapToInt(x -> x).toArray();
class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
int[] hash = new int[1001];
HashSet result = new HashSet<>();
for(int i = 0; i < nums1.length; i++){
hash[nums1[i]] = 1;
}
for(int i = 0; i < nums2.length; i++){
if(hash[nums2[i]] == 1){
result.add(nums2[i]);
}
}
return result.stream().mapToInt(x -> (int) x).toArray();
}
}
四、202.快乐数
- 思路:这个题目无限循环不容易处理,如果是快乐数的话,最终结果为1,如果不是快乐数,无限循坏下去平方和会重复出现,可以用set,一旦出现重复的话就不是快乐数。
class Solution {
int getSum(int n){
int sum = 0;
while(n > 0){
sum += (n % 10) * (n % 10);
n = n / 10;
}
return sum;
}
public boolean isHappy(int n) {
Set record = new HashSet();
while(n != 1 && !record.contains(n)){
record.add(n);
n = getSum(n);
}
return n == 1;
}
}
五、1. 两数之和
- 这题是数组下标和值都需要保存,可以用map映射,key存数组里的数,value存其下标。
- 遍历数组,判断target - nums[i]是否在map中出现过,出现过就是存在符合题意的两个数;没出现过,就将该值存入map。
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> record = new HashMap();
for(int i = 0; i < nums.length; i++){
int s = target - nums[i];
if(record.containsKey(s)){
res[1] = i;
res[0] = record.get(s);
break;
}
record.put(nums[i],i);
}
return res;
}