視窗陣列最大值及其應用

2021-09-25 05:06:00 字數 3289 閱讀 3620

描述:視窗大小為w,陣列長度為n,求每個視窗陣列的最大值,如下題返回乙個陣列為 [5 5 5 4 6 7]

流程: 準備乙個雙端佇列,存放視窗陣列最大值的下標準,雙端佇列保證從左往右遞增,不包括等於,

1)視窗加數(r往右邊移動):考察雙端佇列尾部和陣列當前數的關係,尾部數大,直接從隊尾入隊,否則彈出,直到遇到尾部大於當前數的才將該數從隊尾入隊。

2)視窗減數(l往有邊移動):考察雙端佇列的首部元素是否過期,過期則彈出即可,否則不彈出。

這裡保證雙端佇列從大到小,相等也不行,因為相等不跟新的話最大值可能是前乙個視窗留下來的。 

前面為了方便理解在雙端佇列中存放的數視窗的最大值,最後的方法就是存放的數原陣列的下標,這樣既可可以通過索引得到值,又可以得到該值在原陣列的位置。

實現**:

#include#include#includeusing namespace std;

vectorgetmaxvaluewindow(int arr, int arr_len, int w)

dequedq;

int l = 0;//視窗左邊界

int r = 0;//視窗右邊界

for (int i = 0; i < arr_len; ++i)

dq.push_back(i);

if (r - l + 1 != w)//還沒到視窗,右邊r移動

方法一:暴力解,兩個for迴圈搞出所有子陣列,然後用乙個函式判斷該子陣列是否滿足情況即可:

1)for迴圈遍歷,得到子陣列的下標: 

int getnum1(int arr, int arr_len, int num) 

} }return res;

}

2)isvlid函式判斷子陣列是否滿足條件:

bool isvalid(int arr,int start, int end,int num) 

return max - min <= num;

}

上述那個for兩個迴圈o(n^2)然後isvalid又是o(n),所以是o(n^3)...

方法二:o(n)的時間複雜度

思路:1)如果乙個視窗陣列滿足max-min<=num,則其內部所有子陣列都滿足max-min<=num。因為其子陣列中的sub_max

只能比max小,sub_min只能比min大,之差所以一定滿足<=num.

2)如果乙個視窗陣列滿足max-min<=num,再增加乙個元素就不達標了,那麼視窗無論繼續增加多少元素都不達標,因為繼續擴只能讓max變大min變小的可能性增加。

3)理解了1和2思路就會變得異常簡單。讓l停留在0,r從0往右邊擴,直到遇到乙個不達標的停止,則該視窗內所有子陣列都達標,統計達標的子陣列個數;然後l前進一步,視窗內有可能就會達標了,所以此時讓r繼續擴,就有l每前進一步r就往右走。這樣準備兩個雙端佇列,乙個存放視窗最大陣列,乙個存放視窗最小陣列即可。

測試**: 

#include#include#includeusing namespace std;

bool isvalid(int arr, int start, int end, int num);

//暴力搜尋

int getnum1(int arr, int arr_len, int num)

} }return res;

}bool isvalid(int arr, int start, int end, int num)

return max - min <= num;

}//視窗陣列最大值方法

int getnum2(int arr, int arr_len,int num)

dequedq_max;

dequedq_min;

int l = 0;//視窗左邊界

int r = 0;//視窗右邊界

while (l < arr_len)

dq_max.push_back(r);

//視窗陣列的最小值

while (!dq_min.empty() && arr[dq_min.back()] >= arr[r])

dq_min.push_back(r);

if (arr[dq_max.front()] - arr[dq_min.front()] > num)

r++;

} if (dq_max.front() == l)

if (dq_min.front() == l)

res += r - l;//這個邊界需要注意,是r-l而不是r-l+1是因為r在迴圈中已經到下乙個位置了。

//如:0-3本來有子陣列:0-0,0-1,0-2,0-3 就是3-0+1=4個,但是現在在while中r已經來到了4的位置,所以就是直接r-l.

佇列及其應用(滑動視窗求最大值)

一 佇列 queue 1 佇列的特點 佇列 queue 與棧一樣,是一種線性儲存結構,它具有如下特點 note 1 佇列中的資料元素遵循 先進先出 first in first out 的原則,簡稱fifo結構。2 在隊尾新增元素,在隊頭刪除元素。佇列在棧在計算機中應用相當廣泛,包括廣度優先搜尋 c...

生成視窗最大值陣列

題目描述 有乙個整型陣列arr和乙個大小為w的視窗從陣列的最左邊滑到最右邊,視窗每次向右邊滑乙個位置,求每一種視窗狀態下的最大值。如果陣列長度為n,視窗大小為w,則一共產生n w 1個視窗的最大值 輸入描述 第一行輸入n和w,分別代表陣列長度和視窗大小 第二行輸入n個整數x,表示陣列中的各個元素 輸...

生成視窗最大值陣列

有乙個整型陣列arr和乙個大小為w的視窗從陣列的最左邊滑到最右邊,視窗每次向右邊滑乙個位置,求每一種視窗狀態下的最大值。如果陣列長度為n,視窗大小為w,則一共產生n w 1個視窗的最大值 輸入描述 第一行輸入 n 和 w 分別代表陣列長度和視窗大小 第二行輸入 n 個整數 x ix i xi 表示陣...