還是今天的每日一題,今天的是乙個中等難度的題目。先看一下題目描述吧。
簡單解釋一下就是尋找陣列中每乙個元素的下乙個比它大的元素,這個陣列是乙個迴圈陣列。
看到這個題目,果然我只想得到暴力解法。所謂的暴力解法,就是遍歷陣列中每乙個元素,然後再從當前元素開始再遍歷陣列,直到找到比當前元素大的下乙個元素,然後開始下一輪遍歷。這個方法的時間複雜度很顯然的o(n**2)。
class
solution
:def
nextgreaterelements
(self, nums: list[
int])-
> list[
int]
: n =
len(nums)
result =
for i in
range(0
,n):
if nums[i]
==max
(nums):-
1)# if i==n-1:
# for k in range(0,n):
# if nums[k]>nums[i]:
# break
for j in
range
(i+1
,n):
if nums[j]
>nums[i]:)
break
iflen
(result)
for k in
range(0
,i):
if nums[k]
>nums[i]:)
break
return result
for迴圈第乙個判斷的意思是如果為陣列中最大的元素,那麼是找不到下乙個更大元素的,按照題目要求直接新增-1。接下來就是從當前元素開始往後遍歷,如果遍歷到陣列最後,結果陣列中都還沒有新增元素,說明陣列後面沒有比當前元素更大的元素。那麼因為這是乙個迴圈陣列,所以我們需要再從陣列開始往後找。如果找到更大元素,那麼就直接退出迴圈。開始對下乙個元素迴圈。
然而,經過我多次修改之後,我滿以為這次可以通過了。沒想到測試用例直接來了乙個[0,9999]的陣列,我這個n的平方時間複雜度的演算法毫無疑問超出時間限制了。?
於是還是得找到效率更高的演算法。
我們先看一下前面說的暴力解法它為什麼這麼慢,如果我們有乙個陣列是[5,4,3,2,1,6],用暴力法的話前面五個數每乙個都要遍歷到最後乙個數才能找到比它更大的數,但是因為4,3,2,1都比5小,因此實際上5後面比5大的數是6,因為這幾個數還是遞減的,那麼4,3,2,1就不用判斷了,他們後面比他們大的數肯定也是6,這樣的話我們就能節省時間了。這裡就可以用乙個單調棧來實現,所謂單調棧,就是棧內元素按照單調遞增或遞減的順序加入。我們每次判斷棧頂元素跟當前元素的大小關係,如果小於棧頂元素,那就加入棧內,如果大於棧頂元素棧內元素出棧並且在結果陣列中加入當前元素。如果棧為空的話同樣把當前元素加入棧內。
class
solution
:def
nextgreaterelements
(self, nums: list[
int])-
> list[
int]
: n =
len(nums)
ret =[-
1]* n stk =
list()
for i in
range
(n *2-
1):while stk and nums[stk[-1
]]< nums[i % n]
: ret[stk.pop()]
= nums[i % n]
return ret
今天的每日一題學到的主要內容就是單調棧了,這個資料結構和技巧應該挺有用的,記錄一下,經常複習。 LeetCode刷題筆記 31 下乙個排列
實現獲取下乙個排列的函式,演算法需要將給定數字序列重新排列成字典序中下乙個更大的排列。如果不存在下乙個更大的排列,則將數字重新排列成最小的排列 即公升序排列 必須原地修改,只允許使用額外常數空間。首先,我們觀察到對於任何給定序列的降序,沒有可能的下乙個更大的排列。9,5,4,3,1 我們需要從右邊找...
LeetCode刷題筆記 31下乙個排列
實現獲取下乙個排列的函式,演算法需要將給定數字序列重新排列成字典序中下乙個更大的排列。如果不存在下乙個更大的排列,則將數字重新排列成最小的排列 即公升序排列 必須原地修改,只允許使用額外常數空間。示例 輸入 輸出 1,2,3 1,3,2 3,2,1 1,2,3 1,1,5 1,5,1 舉乙個具體的例...
leetcode503 下乙個更大的元素
難度 中等 題目 給定乙個迴圈陣列 最後乙個元素的下乙個元素是陣列的第乙個元素 輸出每個元素的下乙個更大元素。數字 x 的下乙個更大的元素是按陣列遍歷順序,這個數字之後的第乙個比它更大的數,這意味著你應該迴圈地搜尋它的下乙個更大的數。如果不存在,則輸出 1。示例 1 輸入 1,2,1 輸出 2,1,...