1. 程式人生 > >劍指offer(九) 棧的壓入彈出序列,從上往下列印二叉樹,二叉搜尋樹的後序遍歷序列

劍指offer(九) 棧的壓入彈出序列,從上往下列印二叉樹,二叉搜尋樹的後序遍歷序列

棧的壓入、彈出序列

題目描述

輸入兩個整數序列,第一個序列表示棧的壓入順序,請判斷第二個序列是否可能為該棧的彈出順序。假設壓入棧的所有數字均不相等。例如序列1,2,3,4,5是某棧的壓入順序,序列4,5,3,2,1是該壓棧序列對應的一個彈出序列,但4,3,5,1,2就不可能是該壓棧序列的彈出序列。(注意:這兩個序列的長度是相等的)

解題思路:

設定三個棧,一個pushV,一個popV, 一個輔助stack,把資料從pushv到stack中壓,如果壓入stack中的元素與popv棧首元素相同,則pushV ,popV直接出棧,不必壓入stack,直到pushV中沒有元素,判斷stack中出棧元素和popv中出棧是否一致,如果popv中元素全部彈出,說明彈出序列一致,兩個序列長度相同,就結束了。

程式碼:

# -*- coding:utf-8 -*-
class Solution:
    def IsPopOrder(self, pushV, popV):
        # write code here
        stack = []
        while popV:
#如果第一個元素都相同,則直接彈出,壓入棧為空還是要比的
#一開始為空,不需要彈出,但是壓空了就要比彈出
            if pushV and pushV[0]==popV[0]:
                popV.pop(0)
                pushV.pop(0)
#如果stack最後一個元素與popV第一個元素相同,這就是壓完了之後彈出的過程中進行比較。
            elif stack and stack[-1] == popV[0]:
                stack.pop()
                popV.pop(0)
            elif pushV:
                stack.append(pushV.pop(0))
            else:
                return False
        return True
    

從上往下列印二叉樹

題目描述

從上往下打印出二叉樹的每個節點,同層節點從左至右列印。

解題思路:

廣度優先保證從左到右,  層次遍歷保證從上到下,廣度用佇列實現,深度用棧實現,然後左右子樹遞迴。

程式碼:

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    # 返回從上到下每個節點值列表,例:[1,2,3]
    def PrintFromTopToBottom(self, root):
        # write code here
        if not root:
            return []
        queue = []
        result = []
        
        queue.append(root) #找到root,遍歷root左右子樹
        while len(queue)>0:
            node = queue.pop(0)
            result.append(node.val)
            if node.left:
                queue.append(node.left)
            if node.right:
                queue.append(node.right)
        return result

二叉搜尋樹的後序遍歷序列

題目描述

輸入一個整數陣列,判斷該陣列是不是某二叉搜尋樹的後序遍歷的結果。如果是則輸出Yes,否則輸出No。假設輸入的陣列的任意兩個數字都互不相同。

解題思路:

二叉搜尋樹又是二叉排序樹:

1左子樹結點小於根節點,右子樹大於根節點

2最後一個元素為根節點,

步驟:
1. 找到根節點
2. 遍歷序列,找到第一個大於等於根結點的元素i,則i左側為左子樹、i右側為右子樹;
3. 我們已經知道i左側所有元素均小於根結點,那麼再依次遍歷右側,看是否所有元素均大於根結點;若出現小於根結點的元素,則直接返回false;若右側全都大於根結點,則:
4. 分別遞迴判斷左/右子序列是否為後序序列;

程式碼:

# -*- coding:utf-8 -*-
class Solution:
    def VerifySquenceOfBST(self, sequence):
        # write code here
        if not sequence:
            return False
        
        root = sequence[-1]
        
        i=0 
        for node in sequence[:-1]:
            if node > root:
                break
            i+=1
        
        for node in sequence[i:-1]:
            if node < root: #是否右子樹都》root
                return False
        
        left = True
        if i>0:
            left = self.VerifySquenceOfBST(sequence[:i])
        #i>0,意味著i=0or1的時候,兩個元素沒有排序之分,3個元素就有了左右子樹之分
        right = True
        #len(sequence)>3 有左右子樹之分
        if i < len(sequence)-2 and left:
            right = self.VerifySquenceOfBST(sequence[i+1:])
        return left and right