问题一:滑动窗口的最大值
问题描述:
给定一个数组 nums 和滑动窗口的大小 k,请找出所有滑动窗口里的最大值。
示例:
输入: nums = [1,3,-1,-3,5,3,6,7], 和 k = 3
输出: [3,3,5,5,6,7]
解释:
滑动窗口的位置 最大值
--------------- -----
[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
提示:
你可以假设 k 总是有效的,在输入数组不为空的情况下,1 ≤ k ≤ 输入数组的大小。
解题思路:
双指针移动,统计最大值。
代码实现:
public int[] maxSlidingWindow(int[] nums, int k) {
if(nums.length<=0) return new int[0];
List<Integer> list = new ArrayList<Integer>();
int l = 0;
int r = k-1;
while(r<nums.length) {
list.add(max(nums, l, r));
l++; r++;
}
int[] res = new int[list.size()];
for(int i=0; i<res.length; i++) {
res[i] = list.get(i);
}
return res;
}
private int max(int[] nums, int l, int r) {
int max = Integer.MIN_VALUE;
for(int i=l; i<=r; i++) {
if(nums[i]>max)
max = nums[i];
}
return max;
}
提交结果:
问题二:队列的最大值
问题描述:
请定义一个队列并实现函数 max_value 得到队列里的最大值,要求函数max_value、push_back 和 pop_front的均摊时间复杂度都是O(1)。
若队列为空,pop_front 和 max_value 需要返回 -1
示例 1:
输入:
["MaxQueue","push_back","push_back","max_value","pop_front","max_value"]
[[],[1],[2],[],[],[]]
输出: [null,null,null,2,1,2]
示例 2:
输入:
["MaxQueue","pop_front","max_value"]
[[],[],[]]
输出: [null,-1,-1]
解题思路:
使用一个辅助队列进行存储最大值,存储的最大值按照顺序进行排序。当有元素进入队列时,将最大值队列中所有小于当前值的都删除,然后再插入。当元素出队列时,如果是最大值,则把最大值队列中的头元素也删除。
由于队列是先进先出的,所以不必担心最大值队列max为空而队列res不为空的情况。
代码实现:
public class t59队列的最大值 {
private LinkedList<Integer> res ;
private LinkedList<Integer> max ; //用于存储当前队列中的最大值
public t59队列的最大值() {
res = new LinkedList<Integer>();
max = new LinkedList<Integer>();
}
public int max_value() {
if(max.isEmpty()) return -1;
return max.peekFirst();
}
public void push_back(int value) {
res.addLast(value); //不能使用push,push是调用的是addFirst
//把最大值队列max中小于value的都删除,从队尾开始比较
while(!max.isEmpty() && value>max.peekLast())
max.removeLast();
//最后将value添加到最大值队列中,
max.addLast(value);
}
public int pop_front() {
if(res.isEmpty()) return -1;
int t = res.pollFirst();
//如果删除的是最大值,则把最大值队列中的头元素也删除
if(max.peekFirst()==t)
max.removeFirst();
return t;
}
}
提交结果: