两种不同的Map用法
1. 计数Map(记录出现次数)
java
Map<Character, Integer> countMap = new HashMap<>();
countMap.put('a', 3); // 记录'a'出现了3次
int count = countMap.get('a'); // 得到3
2. 位置索引Map(记录出现位置)
java
Map<Character, Integer> indexMap = new HashMap<>();
indexMap.put('a', 3); // 记录'a'最近一次出现在位置3(索引)
int index = indexMap.get('a'); // 得到3(是位置,不是次数)
下面的代码题则用到哈希表记录索引位置:
题目:给定一个字符串 s ,请你找出其中不含有重复字符的最长子串 的长度
//方法:滑动窗口+双指针
class Solution {
public int lengthOfLongestSubstring(String s) {
Map<Character,Integer> cnt = new HashMap<>();//用哈希表
int n = s.length();
int maxcount = 0;//定义最小字串的长度
int left = 0;//定义左指针 左指针会指向不含有重复字串的最左端
for(int right = 0; right < n; right++){
char c = s.charAt(right);//获取右指针指向的字符
if(cnt.containsKey(c) && cnt.get(c) >= left){//说明指向的字符存在于哈希表内部当中 这里用到的就是索引位置
left = cnt.get(c) + 1;//更新左指针位置
}
//说明指向元素没含在哈希表当中
cnt.put(c,right); 设置的也是索引
//更新最小字串长度
maxcount = Math.max(maxcount,(right - left + 1));
}
return maxcount;
}
}
下面这道题就是用哈希表记录的是个数不是索引位置:
题目:
给你一个整数数组 nums 和两个正整数 m 和 k 。
请你返回 nums 中长度为 k 的 几乎唯一 子数组的 最大和 ,如果不存在几乎唯一子数组,请你返回 0 。
如果 nums 的一个子数组有至少 m 个互不相同的元素,我们称它是 几乎唯一 子数组。
子数组指的是一个数组中一段连续 非空 的元素序列。
class Solution {
public long maxSum(List<Integer> nums, int m, int k) {
Integer[] a = nums.toArray(Integer[]::new);//将集合list换成数组 方便后续操作
long s = 0;//记录窗口中的和
long ans = 0;//记录最终最大的和值
//创建哈希表
Map<Integer, Integer> cnt = new HashMap<>();
for(int i = 0; i < a.length; i++){
s += a[i];//先加和
cnt.merge(a[i], 1, Integer::sum);//判断hash表中a[i]是否存在 如果存在 把它的值加1 如果不存在 则在hash表中添加 a[i] 并把值设为1
int left = i - k + 1;//左指针
if(left < 0){ //说明窗口值不足k
continue;
}
//2.窗口已经足够k 需要更新
if(cnt.size() >= m){ //cnt中不同的元素 大于等于m个 满足要求时
ans = Math.max(ans,s); //更新ans值
}
int out = a[left];//获得要扔出去的元素
s -= out;//先从s中减掉
int c = cnt.get(out);//获取它在hash中的次数
if(c > 1){
cnt.put(out,c-1);//如果至少出现了两次就减1次
}else{
cnt.remove(out);//如果只出现一次 那么就直接从hash表中删除就好
}
}
return ans;
}
}