子串
560. 和为 K 的子数组
java
// 前缀和注意map默认添加一个(0, 1)
// 建议使用Java 8的新方法merge()是原子操作,而之前方法是两步并发场景可能有竞争
// 使用lambda表达式或者Integer的静态方法都行
class Solution {
public int subarraySum(int[] nums, int k) {
int ans = 0, curSum = 0;
Map<Integer, Integer> map = new HashMap<>();
map.put(0, 1);
for (int num : nums) {
curSum += num;
ans += map.getOrDefault(cursum - k, 0);
// map.put(cursum, map.getOrDefault(cursum, 0) + 1);
// map.merge(cursum, 1, (oldval, newval) -> oldval + newval);
map.merge(cursum, 1, Integer::sum);
}
return ans;
}
}239. 滑动窗口最大值
java
// 双端队列,单调递减,offerLast、peekLast、peekFirst、pollLast、pollFirst
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
int[] ans = new int[nums.length - k + 1];
// 双端队列记录元素下标,确保队列内元素在窗口范围k内
Deque<Integer> deque = new ArrayDeque<>();
for (int i = 0; i < nums.length; i++) {
// 确保双端队列的单调递减,新元素将之前比他小的元素排除
while (!deque.isEmpty() && nums[i] >= nums[deque.peekLast()]) {
deque.pollLast();
}
deque.offerLast(i);
// 如果窗口左端越过第一个元素,队首出队,>=也行
if (i - deque.peekFirst() == k) {
deque.pollFirst();
}
// 在i满足条件后才添加入答案
if (i >= k - 1) {
ans[i - k + 1] = nums[deque.peekFirst()];
}
}
return ans;
}
}