算法原理
1.哈希表是什么?
哈希表是存储数据的容器
2.有啥用?
"快速"查找某个元素(最多可以达到O(1))
3.什么时候用?
当我们频繁的查找某一个数时,可以用哈希表,也可以用二分
4.怎么用?
1.容器(哈希表)
2.用数组模拟简易哈希表(字符串中的"字符",数据范围很小的时候)
题目解析
1.两数之和
https://leetcode.cn/problems/two-sum/description/
题目描述
给定一个整数数组nums和一个目标值target,请你在该数组中找出和为t的那两个数,并返回数组下标
例如: nums=2,7,11,15 t=9 输出:0,1
算法原理
解法一:暴力枚举(固定一个数,往前加)
解法二:哈希表做优化
2,7,11,15 t=9
将11扔进哈希表的时候,因为t=9,所以我们要找t=-2,在哈希表中找
代码实现
java
class Solution {
public int[] twoSum(int[] nums, int target) {
Map<Integer,Integer> map=new HashMap<>();
int n=nums.length;
for(int i=0;i<n;i++){
int x=target-nums[i];
if(map.containsKey(x)){
return new int[]{i,map.get(x)};
}
map.put(nums[i],i);
}
return new int[]{};
}
}
2.判断是否互为字符重排
https://leetcode.cn/problems/check-permutation-lcci/description/
题目描述
给定两个字符串s1和s2(由小写字母构成),请编写一个程序,确定一个字符串重新排列后,能否成为另一个字符串
eg: s1="abc" s2="bac" ->true
算法原理
s1每个字符出现个数与s2中每个字符出现次数,完全相同
hash1->存s1 hash2->存s2 用数组模拟
策略二:只使用一个哈希表->只统计s1,遍历s2再减,有负数返回false
如果字符串长度不相等直接false
代码实现
java
class Solution {
public boolean CheckPermutation(String s1, String s2) {
if(s1.length()!=s2.length()){
return false;
}
int[] hash=new int[26];
for(int i=0;i<s1.length();i++){
hash[s1.charAt(i)-'a']++;
}
for(int i=0;i<s2.length();i++){
hash[s2.charAt(i)-'a']--;
if(hash[s2.charAt(i)-'a']<0){
return false;
}
}
return true;
}
}
3.存在重复元素
https://leetcode.cn/problems/contains-duplicate/description/
题目描述
给定一个整数数组nums,如果任一值在数组中至少出现2次,返回true,如果每个元素互不相同,返回false
eg:1,2,3,1 ->true 1,2,3,4->false
算法原理
和T1找两数之和类似(这里我们就是相当于找numsi)
代码实现
java
class Solution {
public boolean containsDuplicate(int[] nums) {
Set<Integer> set=new HashSet<>();
for(int x:nums){
if(set.contains(x)){
return true;
}
set.add(x);
}
return false;
}
}
4.存在重复元素二
https://leetcode.cn/problems/contains-duplicate-ii/description/
题目描述
给定nums和一个k,判断数组中是否存在两个不同索引i和j,满足numsi==numsj,且absi-j<=k,存在返回->true,不存在,返回->false
eg:1,2,3,1 k=3->返回true
1,0,1,1 k=1 返回true
算法原理
1,0,0,1,3,1,4 k=2
hash<Integer,Integer> 第一个Integer存的是numsi,第二个Integer存的是i(可以覆盖,因为题上要求abs(绝对值))
代码实现
java
class Solution {
public boolean containsNearbyDuplicate(int[] nums, int k) {
Map<Integer,Integer> hash=new HashMap<>();
for(int i=0;i<nums.length;i++){
if(hash.containsKey(nums[i])){
if(i-hash.get(nums[i])<=k)
return true;
}
hash.put(nums[i],i);
}
return false;
}
}
5.字母异位词重组
https://leetcode.cn/problems/group-anagrams/description/
题目描述
给定一个字符串数组,请将字母异位词组合在一起,可以按任意顺序返回结果列表
字母异位词是由重新排列源单词的所有字母得到的一个新单词
strs"eat","tea","tan","ate","nat","bat"
输出\["bat","nat","tan","ate","tea","eat"]
算法原理
解法:哈希表
1.判断2个字符串是否是字母异位词(排序)
2.如何分组<String,String\[\]>
"aet"->"eat","tea","ate"
"ant"->"tan","nat"
"abt"->"bat"
代码实现
java
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
Map<String,List<String>> hash=new HashMap<>();
for(String s:strs){
char[] tmp=s.toCharArray();
Arrays.sort(tmp);
String str=new String(tmp);
if(!hash.containsKey(str)){
hash.put(str,new ArrayList<>());
}
hash.get(str).add(s);
}
return new ArrayList(hash.values());
}
}