239. Sliding Window Maximum
You are given an array of integers
nums
, there is a sliding window of sizek
which is moving from the very left of the array to the very right. You can only see thek
numbers in the window. Each time the sliding window moves right by one position.Return the max sliding window.
Example 1:
Input: nums = [1,3,-1,-3,5,3,6,7], k = 3 Output: [3,3,5,5,6,7] Explanation: Window position Max --------------- ----- [1 3 -1] -3 5 3 6 7 3 1 [3 -1 -3] 5 3 6 7 3 1 3 [-1 -3 5] 3 6 7 5 1 3 -1 [-3 5 3] 6 7 5 1 3 -1 -3 [5 3 6] 7 6 1 3 -1 -3 5 [3 6 7] 7
A monotonically decreasing queue单调队列 is a data structure that only keeps elements in decreasing order. Any element that is larger than the current maximum is removed.
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
int n = nums.length;
int[] res = new int[n - k + 1];
int idx = 0;
Deque<Integer> queue = new ArrayDeque<>();
for (int i = 0; i < n; i++) {
// remove elements outside of the sliding window
//check if the index at the front of the queue is outside the current window bounds.
while (!queue.isEmpty() && queue.peekFirst() < i - k + 1) {
queue.pollFirst();
}
// remove smaller elements from the end of the queue
while (!queue.isEmpty() && nums[queue.peekLast()] < nums[i]) {
queue.pollLast();
}
// add current elements index to the queue
queue.offerLast(i);
// If the sliding window has reached its minimum size (contains k elements),
// add the maximum element to the result
if (i >= k - 1) {
res[idx++] = nums[queue.peekFirst()];
}
}
return res;
}
}
TC:O(n)
SC: O(k)
347. Top K Frequent Elements
Given an integer array
nums
and an integerk
, return thek
most frequent elements. You may return the answer in any order.
1. use map ->(key: element, value: count)
2. use heap, PriorityQueue
Need to review heap knowledge
PriorityQueue<Integer> heap = new PriorityQueue<>()
need to come back to it once I learn heap.
class Solution {
public int[] topKFrequent(int[] nums, int k) {
// 优先级队列,为了避免复杂 api 操作,pq 存储数组
// lambda 表达式设置优先级队列从大到小存储 o1 - o2 为从小到大,o2 - o1 反之
PriorityQueue<int[]> pq = new PriorityQueue<>((o1, o2) -> o1[1] - o2[1]);
int[] res = new int[k]; // 答案数组为 k 个元素
Map<Integer, Integer> map = new HashMap<>(); // 记录元素出现次数
for(int num : nums) map.put(num, map.getOrDefault(num, 0) + 1);
for(var x : map.entrySet()) { // entrySet 获取 k-v Set 集合
// 将 kv 转化成数组
int[] tmp = new int[2];
tmp[0] = x.getKey();
tmp[1] = x.getValue();
pq.offer(tmp);
// 下面的代码是根据小根堆实现的,我只保留优先队列的最后的k个,只要超出了k我就将最小的弹出,剩余的k个就是答案
if(pq.size() > k) {
pq.poll();
}
}
for(int i = 0; i < k; i ++) {
res[i] = pq.poll()[0]; // 获取优先队列里的元素
}
return res;
}
}