方法1:代码最多,也是最容易写的
滑动窗口,就是用双端列表实现,插入都是在尾端,左端第一个元素一定是最大值,数组也是两个指针,l和r,r每次向右移动一个位置,然后插入队列,就是和队列的右端进行比较,如果大于右端,右端弹出(不要了,不会影响结果,没用的),一直到遇到等于或者大于他的,然后插入,如果l移动一个位置,就要看左端是否失效(就是是否此位置不在窗口中了),或者用l和队列的左端元素比较,看是否相等,相等就poll两个做法其实一个性质,就是poll掉失效最大值。当然这是窗口可变不可变都可以用,如果窗口不可变,一个指针就可以(右指针)
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
if(nums.length==0){
int[] temp=new int[0];
return temp;
}
LinkedList<Integer> hua=new LinkedList();
int[] res=new int[nums.length-k+1];
//初始化第一个窗口
for(int i=0;i<k;i++){
while(!hua.isEmpty()&&nums[i]>nums[hua.peekLast()]){
hua.pollLast();
}
hua.addLast(i);
}
int i=0;
res[i++]=nums[hua.peekFirst()];
for(int l=1,r=k;r<nums.length;l++,r++){
while(!hua.isEmpty()&&nums[r]>nums[hua.peekLast()]){
hua.pollLast();
}
hua.add(r);
if(hua.peekFirst()==l-1){
hua.pollFirst();
}
res[i++]=nums[hua.peekFirst()];
}
return res;
}
}
第二版第二遍做的
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
if(nums.length==0||nums==null){
//怎么返回[]呢,就是这么做,唯一不用指定个数的,哈哈
return new int[]{};
}
int [] res=new int[nums.length-k+1];//结果数组
int j=0;
LinkedList<Integer> ls=new LinkedList();
int left=0;
int right=0;
while(right<nums.length){
if(right<k){
insert(right++,ls,nums);
if(right==k){
res[j++]=nums[ls.peekFirst()];
}
continue;
}
insert(right++,ls,nums);
//左边弹一个
if(left++==ls.peekFirst()){//只需要判断下标是否过期就可以,不用比较值,其实结果数组根本就不是存储值,而是存储下标,下标可以说明什么下标是过期,是最有效的。
ls.pollFirst();
}
res[j++]=nums[ls.peekFirst()];
}
return res;
}
public void insert(int i,LinkedList ls,int[] nums){
while(!ls.isEmpty()&&nums[i]>=nums[(int)ls.peekLast()]){
ls.pollLast();
}
ls.add(i);
}
}
修正为单指针版本(固定长度模板)(这个第二遍还是写不出来,而且看了思路,还是细节一直报错,所以你懂的,写 写 写 多练多练 多练 直到你背下来)
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
if(nums.length==0){
int[] temp=new int[0];
return temp;
}
LinkedList<Integer> hua=new LinkedList();
int[] res=new int[nums.length-k+1];
int j=0;
for(int i=0;i<nums.length;i++){
if(!hua.isEmpty()&&hua.peek()<i-k+1){
hua.pollFirst();
}
while(!hua.isEmpty()&&nums[i]>nums[hua.peekLast()]){
hua.pollLast();
}
hua.add(i);
if(i-k+1>=0){
res[j++]=nums[hua.peekFirst()];
}
}
return res;
}
}
Leetcode795区间子数组的数量
方法1:暴力做法,当然一定超时,on3次方
class Solution {
public int numSubarrayBoundedMax(int[] A, int L, int R) {
int res=0;
for(int i=0;i<A.length;i++){
for(int j=i;j<A.length;j++){
int max=Max(A,i,j);
if(max>=L&&max<=R){
res++;
}
}
}
return res;
}
public int Max(int[] a,int i,int j){
int max=0;
for(int k=i;k<=j;k++){
max=Math.max(max,a[k]);
}
return max;
}
}