輸入乙個整數陣列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...