給定乙個陣列 nums,有乙個大小為 k 的滑動視窗從陣列的最左側移動到陣列的最右側。你只可以看到在滑動視窗內的 k 個數字。滑動視窗每次只向右移動一位。
返回滑動視窗中的最大值。
可以想到維護乙個類似單調棧的資料結構,單調佇列,佇列內的資料嚴格單調遞減,因此每次尋找最大值時就直接返回隊頭即可,滿足o(1)時間複雜度,然後就是維護單調佇列的進隊和出隊操作了,進隊時,從隊尾開始,令所有小於當前值的元素全部出隊,直到碰到比它大的元素,這樣就保證了佇列內的資料嚴格單調遞減了。
出隊操作對應滑動視窗向前滑動時,需要從佇列出乙個元素,只需要考慮出的元素是否等於隊頭元素即可,因為如果不是隊頭元素,就證明不是最大值,已經被覆蓋了。
class
solution
d.push_back
(nums[i]);
}//進隊第k個元素
else
d.push_back
(nums[i]);
//開始取值
ans.
push_back
(d.front()
);//刪除滑動視窗第乙個元素
if(d.
front()
== nums[i - k +1]
)}}return ans;}}
;
可以將陣列按照k分塊,定義left_max[i]表示從塊頭開始到位置i的最大值,狀態轉移方程為left_max[i] = max(left_max[i - 1], num[i]),特別地,當i % k時,也就是塊開始時,left_max[i] = num[i],方向是從左到右,定義right_max[j]表示從右邊開始,塊頭到位置j的最大值,狀態轉移方程為right_max[j] = max(right_max[j + 1], num[j]),特別地,當j + 1 % k時,right_max[j] = num[j]。
然後,對於[i, i + k - 1]的視窗內,只需要考慮left_max[i - k + 1]和right_max[i]即可。
class
solution;}
if(k ==1)
vector<
int>
left_max
(n);
vector<
int>
right_max
(n);
left_max[0]
= nums[0]
; right_max[n -1]
= nums[n -1]
;for
(int i =
1; i < n; i++
)else
int j = n - i -1;
if((j +1)
% k ==0)
else
} vector<
int> ans;
for(
int i =
0; i < n - k +
1; i++
)return ans;}}
;
239 滑動視窗最大值
給定乙個陣列 nums,有乙個大小為 k 的滑動視窗從陣列的最左側移動到陣列的最右側。你只可以看到在滑動視窗內的 k 個數字。滑動視窗每次只向右移動一位。返回滑動視窗中的最大值。示例 輸入 nums 1,3,1,3,5,3,6,7 和 k 3 輸出 3,3,5,5,6,7 解釋 滑動視窗的位置 最大...
239 滑動視窗最大值
239.滑動視窗最大值 solution deque solution maxindex 暴力法的時間複雜度為 o n k 弊端為每次掃瞄視窗的最大值,每兩次掃瞄之間都會存在重複的值比較,已經知道了他們的最大值是誰了,所以要減少比較次數 為什麼新增的是索引 將i加到隊尾 deque.addlast ...
239 滑動視窗最大值
給定乙個陣列 nums,有乙個大小為 k 的滑動視窗從陣列的最左側移動到陣列的最右側。你只可以看到在滑動視窗內的 k 個數字。滑動視窗每次只向右移動一位。返回滑動視窗中的最大值。高階 示例 輸入 nums 1,3,1,3,5,3,6,7 和 k 3 輸出 3,3,5,5,6,7 解釋 滑動視窗的位置...