代码随想录第十三天|
Leetcode 239. 滑动窗口最大值
题目链接: 滑动窗口最大值
自己的思路:有单调队列的思路但是不会写代码!!!!多练!!!
正确思路:由于是记录窗口中的最大值,如果每次形成一个窗口,再寻找最大值,则复杂度会变大,所以我们考虑空间复杂度为k的单调队列来维护窗口中的元素,这里我们我们队列中存放的是数据的索引,这样比较容易维护窗口的长度;首先维护一个单调递减的双端队列,如果新加入的元素大于等于队尾的元素,则将队尾元素剔除,一直到没有队尾元素大于新加入的元素为止,然后将新加入的元素加到队尾,这样就形成了单调队列,然后我们判断当前队首的元素是否还在窗口中,判断 i i i-deque.peek()是否大于等于k,如果大于等于 k k k,说明当前队首元素已经不在窗口中了,将队首元素剔除,直到在窗口中为止,然后将队首元素加入到res数组中即可。
代码:
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
int length = nums.length;
//存储最后元素的数组
int [] res = new int[length-k+1];
int index = 0;
//双向队列
Deque<Integer> deque = new LinkedList<>();
for (int i =0;i<length;i++){
//位置递减双向队列
while(!deque.isEmpty()&&nums[i]>=nums[deque.peekLast()]){
deque.pollLast();
}
//将当前索引加入
deque.addLast(i);
//判断当前队首的索引是否还在窗口中
if (deque.peek()<=i-k){
deque.poll();
}
//当形成窗口的时候,加入队首元素
if (i+1>=k){
res[index] = nums[deque.peek()];
index++;
}
}
return res;
}
}
复杂度分析:
时间复杂度:
O
(
n
)
\mathcal{O}(n)
O(n)
空间复杂度:
O
(
k
)
\mathcal{O}(k)
O(k)
Leetcode 347. 前 K 个高频元素
题目链接: 前 K 个高频元素
自己的思路:只想到了用Map来存储每个元素出现的个数,没有想到大顶堆来存放数组
正确思路:因为涉及到了元素出现的次数,所以优先想到使用Map来存储各个数据以及其出现的次数,题目要返回前k个高频元素,所以可以使用大顶堆来存放数据及出现的次数,然后直接返回大顶堆的前k个数据即可。
代码:
class Solution {
public int[] topKFrequent(int[] nums, int k) {
int[] res = new int[k];
//Map存储数组中元素出现的个数
Map<Integer,Integer> map = new HashMap<>();
for (int i =0;i<nums.length;i++){
map.put(nums[i],map.getOrDefault(nums[i],0)+1);
}
//大顶堆,因为后面是pair2[1]-pair1[1],如果返回为正,则第二个参数排前面,否则第一个参数排前面
//队首存放出现次数最多的数
PriorityQueue<int[]> pq = new PriorityQueue<>((pair1,pair2)->pair2[1]-pair1[1]);
for (Map.Entry<Integer,Integer> entry:map.entrySet()){
pq.add(new int[]{entry.getKey(),entry.getValue()});
}
for (int i =0;i<k;i++){
res[i] = pq.poll()[0];
}
return res;
}
}
复杂度分析:
时间复杂度:
O
(
n
)
\mathcal{O}(n)
O(n)
空间复杂度:
O
(
n
)
\mathcal{O}(n)
O(n)