單調佇列 LeetCode1673

2021-10-11 13:51:37 字數 1679 閱讀 1730

輸入乙個整數陣列nums和乙個正整數k,返回長度為k的子串行使得其字典序最小(最具競爭力)。

示例 1:

輸入:nums = [3,5,2,6], k = 2

輸出:[2,6]

解釋:在所有可能的子串行集合 中,[2,6] 最具競爭力。

示例 2:

輸入:nums = [2,4,3,3,5,4,9,6], k = 4

輸出:[2,3,3,4]

1 ≤

\leq

≤ nums.length ≤

\leq≤10

510^5

1050 ≤

\leq

≤ nums[i] ≤

\leq≤10

910^9

1091 ≤

\leq

≤ k ≤

\leq

≤ nums.length

容易想到:在下標區間[0,n-k]的最小值(假設下標為i

ii)就是答案的第乙個數,接下來在下標區間[i+1,n-k+1]的最小值就是答案的第二個數(假設下標為i

2i_2

i2​),…,以此類推可以得到所有的數。但是如果遍歷求解每個區間的最小值,總時間複雜度是o(n

2)

o(n^2)

o(n2

),顯然會超時。

使用單調佇列:遍歷一遍原陣列,同時維護單調佇列,單調佇列首元素為當前所需區間的最小值。具體做法是:每遍歷乙個新數nums[i],從後往前把單調佇列中比nums[i]大的數刪掉(因為這些數在之後絕對不可能成為所需區間的最小值),然後把nums[i]加入單調佇列。一旦確定某個區間的最小值後,就將頭元素加入答案並從單調佇列去掉,繼續遍歷即可。

拿示例2舉例:nums = [2,4,3,3,5,4,9,6], k = 4

2加入,queue = [2]

4加入,queue = [2,4]

刪掉4,加入3,queue = [2,3]

3加入,queue = [2,3,3]

5加入,queue = [2,3,3,5],此時答案第乙個數確定為首元素2,將2去掉之後繼續遍歷

刪掉5,加入4,queue = [3,3,4],答案第二個數為3,去掉3

9加入,queue = [3,4,9],答案第三個數為3,去掉3

刪掉9,加入6,queue = [4,6],答案第四個數為4

因此答案為[2,3,3,4]。

時間複雜度:每個元素最多加入佇列一次、從佇列中刪除一次,故時間複雜度o(n

)o(n)

o(n)

class

solution

;for

(int i =

1; i < nums.

size()

; i++

) ans.

push_back

(nums[i]);

}//單調佇列的前k個數就是答案

return vector<

int>

(ans.

begin()

,ans.

begin()

+k);}}

;

leetcode 167周賽題解

class solution return ans class solution def getdecimalvalue self,head ans 0while head none ans ans 2 head.val head head.next return ansclass solution...

LeetCode 167 兩數之和

給定乙個已按照公升序排列 的有序陣列,找到兩個數使得它們相加之和等於目標數。函式應該返回這兩個下標值 index1 和 index2,其中 index1 必須小於 index2。說明 返回的下標值 index1 和 index2 不是從零開始的。你可以假設每個輸入只對應唯一的答案,而且你不可以重複使...

leetcode 167 兩數求和

方法二.二分查詢 給定乙個已按照 公升序排列 的整數陣列 numbers 請你從陣列中找出兩個數滿足相加之和等於目標數 target 函式應該以長度為 2 的整數陣列的形式返回這兩個數的下標值。numbers 的下標 從 1 開始計數 所以答案陣列應當滿足 1 answer 0 answer 1 n...