這道題你不來了解一下嗎
阿新 • • 發佈:2021-11-11
棧和排序
問題描述
給你一個由1~n,n個數字組成的一個排列和一個棧,要求按照排列的順序入棧。如何在不打亂入棧順序的情況下,僅利用入棧和出棧兩種操作,輸出字典序最大的出棧序列。
排列:指 1 到 n 每個數字出現且僅出現一次。
示例:
輸入:[2,1,5,3,4]
輸出:[5,4,3,1,2]
分析問題
由於我們只能使用出棧和入棧兩種操作,要想使得出棧序列字典序最大,首先想到的就是令高位儘可能地大,我們出棧的時機就是:當前入棧元素若是大於之後將要入棧的元素,那麼就將其出棧。當元素出棧後,還需要判斷棧頂元素與之後將要入棧元素之間的大小關係,如果此時棧頂元素大於之後將要入棧的元素,那麼就將其出棧,不斷判斷直到棧為空或條件不滿足。
為了快速判斷“當前入棧元素是否大於之後將要入棧的元素”,我們需要建立一個輔助陣列temp,其中temp[i]表示i之後的最大元素。藉助輔助陣列,我們可以以O(1)的時間複雜度去判斷當前入棧元素是否大於之後將要入棧的元素。
下面我們來看一下程式碼的實現。
import sys class Solution: def solve(self , a): n=len(a) res=[] if n==0: return res stack=[] temp=[0]*n temp[n-1]=-sys.maxsize-1 #從右往左遍歷陣列a,然後取填充temp #使得temp[i]表示i之後的最大元素 for i in range(n-2,-1,-1): temp[i]=max(a[i+1],temp[i+1]) #遍歷陣列a for i in range(0,n): if a[i] > temp[i]: #若當前元素大於之後將要入棧的元素,將其加入結果中 res.append(a[i]) # 若棧不為空,且棧頂元素大於temp[i], # 棧頂出棧,加入結果中 while stack and stack[-1] > temp[i]: res.append(stack[-1]) stack.pop() else: stack.append(a[i]) while stack: res.append(stack[-1]) stack.pop() return res
該演算法的時間複雜度是O(n),空間複雜度也是O(n)。