生成窗口的最大值数组
- 思路
其实这个题目单单只要实现的话并不难,一直遍历就好了,但是这样的方法并不能打动面试官,我们需要得到时间复杂度更小的方法才可以赢得面试官的青睐。
主要思路:
这里使用双端队列作为辅助结构进行求解。具体步骤如下:
1.首先遍历当前数组,然后判断双端队列是否为空,若为空,则直接将当前数字的索引放入双端队列的队尾;
2.若当前双端队列不为空,则判断当前双端队列队尾的的索引在原数组中的数字是否小于等于当前遍历到的数字,若是,则弹出,直到当前双端队列尾部所代表的原数组数字大于当前遍历数字,则当前数字的索引放入双端队列的队尾。。
3.同时,我们要判断双端队列中的索引是否过期,并及时的将当前窗口中的最大值放入我们最终需要得到的数组中。该数组的大小为n-w+1。其中n为原数组长度,w为窗口宽度。
import java.util.*;
public class Main{
public static void main(String [] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int w = sc.nextInt();
int [] arr = new int[n];
for(int i=0;i<n;i++){
arr[i]= sc.nextInt();
}
int [] answer = getMaxList(arr,n,w);
for(int i=0;i<answer.length;i++){
System.out.print(answer[i]+" ");
}
}
public static int[] getMaxList(int [] arr,int n,int w){
if(arr==null || w<1 || w>n){
return null;
}
LinkedList<Integer> qmax = new LinkedList();
int [] res = new int[n-w+1];
int index = 0;
for(int i=0;i<n;i++){
while(!qmax.isEmpty() && arr[i]>=arr[qmax.peekLast()]){
qmax.pollLast();
}
qmax.addLast(i);
if(qmax.peekFirst()==i-w){
qmax.pollFirst();
}
if(i>=w-1){
res[index++] = arr[qmax.peekFirst()];
}
}
return res;
}
}