1. 程式人生 > 其它 >這道題你不來了解一下嗎

這道題你不來了解一下嗎

棧和排序

問題描述

給你一個由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)。