239. Sliding Window Maximum
You are given an array of integers nums, there is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k 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
Example 2:
Input: nums = [1], k = 1
Output: [1]
Constraints:
1 <= nums.length <= 105-104 <= nums[i] <= 1041 <= k <= nums.length
题目要求滑动窗口内元素的最大值,排除暴力解的话,需要维护的数据结构必须能返回最大值,且可以在窗口移过最大值元素位置时,将最大值元素移除,且能维持返回当前窗口最大值的能力。 方法比较巧,我没想到。就是考虑在窗口移动时,若新加入的元素为当前窗口最大值,其实意味着维护队列内所有其它的元素都没必要继续维护了,因为在下面k-1次移动时,最大值一定都是当前的新元素。 所以算法为,维护一个deque队列,使得其头部总是为当前滑动窗口的最大值。 为做到这点,有两项要点:
- 在窗口右侧新进入的元素,从队列后部向前扫描,pop所有小于它的元素,因为没必要维护了
- 在窗口左端离开的元素,检查其是否等于最大值,若是,从左端pop元素。
对java仍不熟练,要注意对于deque, push操作会从头部添加 pop操作也是头部出 poll从头部 peek从头部 offer操作是尾部添加 add也是尾部 没有remove操作,必须指定removeFirst 或者removeLast
代码:
import java.util.ArrayDeque;
import java.util.Deque;
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
Deque<Integer> deque = new ArrayDeque<>();
int[] ans = new int[nums.length - k + 1];
int start = 0;
int end = 0;
int count = 0;
while(end < nums.length) {
while(deque.peekLast() != null && deque.peekLast() < nums[end]) {
deque.removeLast();
}
deque.offer(nums[end]);
//System.out.println(end);
//System.out.println(deque);
if(end - start + 1 >= k) {
ans[start] = deque.peekFirst();
if(nums[start] == deque.peekFirst()) {
deque.pollFirst();
}
start++;
}
end++;
}
return ans;
}
}
347. Top K Frequent Elements
Given an integer array nums and an integer k, return the k most frequent elements. You may return the answer in any order.
Example 1:
Input: nums = [1,1,1,2,2,3], k = 2
Output: [1,2]
Example 2:
Input: nums = [1], k = 1
Output: [1]
Constraints:
1 <= nums.length <= 105-104 <= nums[i] <= 104kis in the range[1, the number of unique elements in the array].- It is guaranteed that the answer is unique.
这题用priority queue做,先用map做好数值对次数的map,然后维护一个priority queue,将map中的key value作为pair加入queue内,排序移除次数最小的。
还是对java的系统函数不熟。
代码:
class Solution {
public int[] topKFrequent(int[] nums, int k) {
Map<Integer, Integer> imap = new HashMap<Integer, Integer>();
for(int i : nums) {
imap.put(i, imap.getOrDefault(i,0) + 1);
}
PriorityQueue<int []> pq = new PriorityQueue<>((pair1, pair2)->(pair1[1] - pair2[1]));
for(Map.Entry<Integer, Integer> entry : imap.entrySet()) {
if(pq.size() < k) {
pq.add(new int[]{entry.getKey(), entry.getValue()});
}
else {
if(entry.getValue() > pq.peek()[1]) {
pq.add(new int[]{entry.getKey(), entry.getValue()});
pq.poll();
}
}
}
int[] ans = new int[k];
for(int i=0; i<k; i++) {
ans[i] = pq.poll()[0];
}
return ans;
}
}