提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
前言
一、和为k的子串
这题想用滑动窗口,发现和不是单调递增的,所以不好滑。看了答案有一些想法
java
public class Solution {
public int subarraySum(int[] nums, int k) {
int count = 0, pre = 0;
HashMap < Integer, Integer > mp = new HashMap < > ();
mp.put(0, 1);
for (int i = 0; i < nums.length; i++) {
pre += nums[i];
if (mp.containsKey(pre - k)) {
count += mp.get(pre - k);
}
mp.put(pre, mp.getOrDefault(pre, 0) + 1);
}
return count;
}
}
这里想了用hash表出现重复值怎么办,有可能是断的值,比如7,14,14,count=2但是如果是14,7,14这样的顺序count就是1了,后来看了一下,它是即时计算的,不是最后才算


二、滑动窗口最大值
这里感觉有点像接雨水,维持一个单调队列。但是困难题主要问题还是我的逻辑,怎么样能骗过更多的测试案例。
我想的是右边加左边减,随时记录最大值,但是存在小小的逻辑矛盾。答案代码是,先处理过期,再淘汰,最后再添加并判断,因为一直弹出,所以队列实质上是不满的,也不用考虑数组越界。
java
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
if (nums == null || nums.length == 0) {
return new int[0];
}
Deque<Integer> deque = new ArrayDeque<>(); // 存索引
int[] res = new int[nums.length - k + 1];
int idx = 0;
for (int i = 0; i < nums.length; i++) {
// 1. 过期淘汰(左边出队)
// 如果队头已经在窗口外面了,踢出去
if (!deque.isEmpty() && deque.peekFirst() <= i - k) {
deque.pollFirst();
}
// 2. 维持单调递减(右边清理)
// 当前值比队尾大,队尾不可能是最大值,踢出去
while (!deque.isEmpty() && nums[deque.peekLast()] < nums[i]) {
deque.pollLast();
}
// 3. 入队(右边入队)
deque.addLast(i);
// 4. 记录结果(当窗口形成后)
if (i >= k - 1) {
res[idx++] = nums[deque.peekFirst()];
}
}
return res;
}
}
三、最小覆盖字串
记录一下
java
class Solution {
public String minWindow(String s, String t) {
int[] st=new int [52];
int[] tt=new int [52];
for(int i=0;i<t.length();i++){
tt[t.charAt(i)-'A']++;
}
String s1="";
Deque<Integer> deque=new ArrayDeque<>();
int left=0,right=s.length()-1;
for(int i=0;i<s.length();i++){
for(int j=0;j<s.length();j++){
if(!deque.isEmpty() && deque.peekFirst()>j){
continue;
}
if(tt[s.charAt(j)-'A']==1){
st[s.charAt(j)-'A']++;
deque.addLast(j);
}
if(Arrays.equals(st,tt)){
if(deque.peekLast()-deque.peekFirst()<right-left){
right=deque.peekLast();
left=deque.peekFirst();
}
st[deque.pollFirst()]--;
}
}}
for(;left<right;left++){
s1+=String.valueOf(s.charAt(left));
}
return s1;
}
}
答案:
java
class Solution {
Map<Character, Integer> ori = new HashMap<Character, Integer>();
Map<Character, Integer> cnt = new HashMap<Character, Integer>();
public String minWindow(String s, String t) {
int tLen = t.length();
for (int i = 0; i < tLen; i++) {
char c = t.charAt(i);
ori.put(c, ori.getOrDefault(c, 0) + 1);
}
int l = 0, r = -1;
int len = Integer.MAX_VALUE, ansL = -1, ansR = -1;
int sLen = s.length();
while (r < sLen) {
++r;
if (r < sLen && ori.containsKey(s.charAt(r))) {
cnt.put(s.charAt(r), cnt.getOrDefault(s.charAt(r), 0) + 1);
}
while (check() && l <= r) {
if (r - l + 1 < len) {
len = r - l + 1;
ansL = l;
ansR = l + len;
}
if (ori.containsKey(s.charAt(l))) {
cnt.put(s.charAt(l), cnt.getOrDefault(s.charAt(l), 0) - 1);
}
++l;
}
}
return ansL == -1 ? "" : s.substring(ansL, ansR);
}
public boolean check() {
Iterator iter = ori.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
Character key = (Character) entry.getKey();
Integer val = (Integer) entry.getValue();
if (cnt.getOrDefault(key, 0) < val) {
return false;
}
}
return true;
}
}
作者:力扣官方题解
链接:https://leetcode.cn/problems/minimum-window-substring/solutions/257359/zui-xiao-fu-gai-zi-chuan-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。