日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【面试题 - 最大值减去最小值小于或等于 num 的子数组数量】滑动窗口

發布時間:2023/12/10 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【面试题 - 最大值减去最小值小于或等于 num 的子数组数量】滑动窗口 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題干:

解題報告:

我們用兩個指針(i,j)分別代表窗口的左邊界和右邊界,窗口也就是子數組;
用兩個雙端隊列分別維護這個窗口的最大值和最小值;
當窗口擴大時,即j向右擴展時,窗口內的最大值只會越來越大,而最小值只會越來越小(否則就會等于原來的max和min了),此時,如果max-min>num,則j不應該向右擴展了,因為max-min的范圍只會越來越大;
這時,應該讓窗口縮小,即i向右擴展,這樣max可能會減小,min可能會增大(因為原來的max和min可能會失效,即不在窗口內),這樣max-min才會有<=num的可能;

另一個題解:

1)最簡單的方法,暴力搜索,如何得到全部滿足條件的子數組,
??????????left = 0, res=0;
??????????1:我們left不變 right++直到right=arr.length結束,每次right++我們都得到left~right的最大值,最小值 符合條件res++;
??????????2:然后left++ 重復第一步。

2)首先我們不用遍歷n*n次,
??????????當滿足條件right++ ?不滿足時left++ ?這樣時間復雜度為n*2;
??????????原因:當最大值-最小值>k時 我們right++ 如果arr[right]>最大值 或者arr[right]<最小值 差值都是增大的因此在移動right沒有意義。
???????????left++,將子數組縮小,
???????????如果移除的數字是最大值,那么次大值-最小值 差值縮小;
???????????如果移除的數字是最小值,那么最大值-次小值 差值縮小;
???????????如果移除的是其他數字 差值不變;
???????????這樣的時間復雜度變為n*2。

3)以上兩種方法在left和right移動的過程中都要不斷進行min和max的判斷,提高了時間復雜度。

在遍歷過程中不斷更新qmin和qmax。

其中補充兩個關鍵點:

1)如果nums[i..j]滿足條件, nums[k..j]??(i<= k <= j),都滿足條件;

2)如果nums[i..j]不滿足條件,所有包含 nums[i..j] 的數組都不滿足條件;


AC代碼:

class Solution { public:int getNum(vector<int> nums, int target){if(nums.empty())return 0;deque<int> qmin; //保存窗口內的最小值,遞增 front保存最小的元素位置deque<int> qmax; //保存窗口內的最大值,遞減 front保存最大的元素位置int i = 0, j = 0; //nums[i..j]表示數組的范圍int res = 0; //表示滿足條件的子數組數量//依次找到以nums[0],nums[1]...nums[N - 1]作為第一元素的子數組中滿足條件的數量有多少個,累加while(i < nums.size()){while(j < nums.size()) // j向右拓展,直到不滿足條件{while(!qmin.empty() && nums[qmin.back()] >= nums[j]) // 更新qmin中最小值的indexqmin.pop_back();qmin.push_back(j);while(!qmax.empty() && nums[qmax.back()] <= nums[j]) // 更新qmax中最大值的indexqmax.pop_back();qmax.push_back(j);if(nums[qmax.front()] - nums[qmin.front()] > target) //如果出現不滿足條件的,那么包含以nums[i]起始的窗口的所有子數組都不滿足條件break;j++;}if(qmin.front() == i) // 如果窗口為 0 ,直接彈出qmin.pop_front();if(qmax.front() == i) // 如果窗口為 0 ,直接彈出qmax.pop_front();res += j - i; //如果nums[i..j]滿足條件,則其子數組都滿足條件, 一共 (j - i)個子數組i++; //繼續尋找以nums[i]為起始點的子數組}return res;}};

?

總結

以上是生活随笔為你收集整理的【面试题 - 最大值减去最小值小于或等于 num 的子数组数量】滑动窗口的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。