目录
和为 K 的子数组
想不到,前缀和相减能够获得所有子区间的和,然后使用hashmap记录前缀和,value记录当前和的个数。注意要用前缀和j-i时,需要j>i;前缀和本身也需要判断是否为K。
java
public class 和为K的子数组 {
class Solution {
public int subarraySum(int[] nums, int k) {
int res = 0;
Map<Integer, Integer> map = new HashMap<Integer,Integer>();
int[] s = new int[nums.length];
s[0] = nums[0];
if (nums[0]==k)res++;
map.put(s[0],1);
for (int i = 1; i < nums.length; i++) {
s[i] = s[i-1] + nums[i];
if (s[i]==k) res++;
// s[i] - s[j] = k;
if (map.containsKey(s[i]-k)) res+=map.get(s[i]-k);
map.put(s[i],map.getOrDefault(s[i],0) + 1);
}
return res;
}
}
}
滑动窗口最大值
用ArrayDeque队尾作为栈,每次将元素入栈前将栈中小于该元素的数据出栈,从而保证该元素前面的元素滑出窗口后该元素就是最大值,队头记录了当前窗口内的最大值,需要在输出窗口最大值前将队列中不属于窗口内的值出队首,通过队列记录下标实现。
java
public class 滑动窗口最大值 {
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
int[] res = new int[nums.length - k + 1];
ArrayDeque<Integer> queue = new ArrayDeque<>();
for (int i = 0; i < nums.length; i++) {
// 出栈直到栈中数据都比nums[i]大
while (!queue.isEmpty() && nums[i]>=nums[queue.peekLast()]){
queue.pollLast();
}
// 当前元素入栈
queue.offerLast(i);
// 队首元素即为最大元素
if (i+1>=k){
// 先将不在窗口的元素出队
while (queue.peekFirst()<i+1-k) queue.pollFirst();
res[i+1-k] = nums[queue.peekFirst()];
}
}
return res;
}
}
}
最小覆盖子串
如果窗口内不包含子串那么r右移,包含后l右移直到窗口内不包含子串。