1-7 生成窗口最大值數組

題目描述

  • 計算生成窗口最大值數組

  • 有一個整型數組arr和一個大小爲w的窗口從數組最左邊滑到最右邊。

  • 現在要求實現一個函數,輸入整型數組arr和窗口長度w,輸出一個最大值數組res記錄每個窗口的最大值。
    在這裏插入圖片描述

解題方法1

  • 最簡單粗暴的方法就是直接兩層遍歷,代碼如下。但是時間複雜度爲 n*w 顯然有優化的空間。
public class Test {
    public static void main(String[] args) {
       int [] arr = {4,3,5,4,3,3,6,7};
       int [] res = fun(arr,3);
       for(int a:res){
           System.out.print(a+" ");
       }
    }
    //計算每個窗口最大值並保存到數組返回
    public static int [] fun(int [] arr,int w){
         int [] res = new int[arr.length-w+1];
         for(int i=0;i<arr.length-w+1;i++){
             res[i] = getmax(arr,i,w);
         }
         return res;
    }
    //尋找一個窗口最大值
    public static int getmax(int [] arr,int start,int w){
        int max = arr[start];
        for(int i=start+1;i<start+w;i++){
            if(arr[i]>max){
                max = arr[i];
            }
        }
        return max;
    }
}

解題方法2

  • 可以使用雙端隊列進行優化,隊列中存放元素的下標。
  • 隊頭彈出過期的下標,隊尾壓入值更小或等的下標,彈出值更大的下標。
  • 這樣可以保證隊頭元素指向的永遠是當前窗口最大值。
  • 我們根據arr數組當前遍歷位置i往前推w個元素便可以判斷隊頭是否還在窗口範圍內(是否過期)。
  • 代碼如下:
public class Test {
    public static void main(String[] args) {
       int [] arr = {4,3,5,4,3,3,6,7};
       int [] res = fun(arr,2);
       for(int a:res){
           System.out.print(a+" ");
       }
    }
    //計算每個窗口最大值並保存到數組返回
    public static int [] fun(int [] arr,int w){
         int [] res = new int[arr.length-w+1];
         LinkedList<Integer> queue = new LinkedList<>();
         int index = 0; //index指向res數組的下標
         for(int i=0;i<arr.length;i++){
             //隊列爲空 或者 i指向元素<當前隊尾  將i壓入隊尾
             if(queue.size()==0 || arr[i]<queue.peekLast()){
                 queue.addLast(i);
             }
             //否則 彈出當前隊尾繼續比較 直到當前i指向值<隊尾或者隊列爲空 然後再將i壓入隊尾
             else{
                 while(queue.size()>0 && arr[i]>=arr[queue.peekLast()]){
                     queue.pollLast();
                 }
                 queue.addLast(i);
             }
             //如果當前隊頭過期了 就把隊頭出隊
             if(queue.peekFirst()<(i-w+1)){
                 queue.pollFirst();
             }
             //如果當前可以構成一個窗口了 就將隊頭保存到數組res
             if((i-w+1)>=0){
                 res[index] = arr[queue.peekFirst()];
                 index++;
             }
         }
         return res;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章