560.和为K的子数组
前缀和+哈希表
要查找的子数组为连续的,可以由两个前缀和计算得出,满足题目的条件为preSum[i] - preSum[j-1] = k,所以我们可以用哈希表记录前缀和出现的次数,在遍历到位置 i 时计算出preSum[i] - k ,查看哈希表中是否有对应值,若有则取次数加入结果。
注意,用哈希表记录元素出现次数map.put(preSum , map.getOrDefault(preSum,0)+1);
class Solution {
public int subarraySum(int[] nums, int k) {
int res = 0;
int preSum = 0;
HashMap<Integer,Integer> map = new HashMap<>();
map.put(0,1);
for(int i = 0 ; i<nums.length ; i++){
preSum += nums[i];
if(map.containsKey(preSum-k)){
res += map.get(preSum-k);
}
map.put(preSum , map.getOrDefault(preSum,0)+1);
}
return res;
}
}
239.滑动窗口最大值
利用单调队列,队列中保存索引值,并保持索引对应的元素递减,即如果加入的元素大于当前队尾元素,则弹出队尾元素(while),直到小于队尾元素或队列为空,放入该元素。
这样求滑动窗口的最大值仅需要 peekFirst 的值,每次循环要判断队首的元素索引如果不在窗口中了就要弹出。
注意:Deque的方法 offer、poll、First、Last
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
int[] res = new int[nums.length-k+1];
Deque<Integer> deque = new LinkedList<>();
for(int i = 0 ; i<k ; i++){
while(!deque.isEmpty() && nums[deque.peekLast()]<nums[i]){
deque.pollLast();
}
deque.offerLast(i);
}
res[0] = nums[deque.peekFirst()];
for(int i = k ; i<nums.length ; i++){
while(!deque.isEmpty() && nums[deque.peekLast()]<nums[i]){
deque.pollLast();
}
deque.offerLast(i);
if(deque.peekFirst()<=i-k) deque.pollFirst();
res[i-k+1] = nums[deque.peekFirst()];
}
return res;
}
}