leetcode 145. Binary Tree Postorder Traversal
思路一:
- 使用一個棧stack保存經過的根結點,另一個棧flag保存每個結點的右子樹是否遍歷;
- 如果根結點存在,結點入棧,並把結點的右子樹遍歷結果置為0,代表沒遍歷;
- 把root指向左子樹;
- 如果棧不為空,判斷棧頂元素右子樹是否存在以及是否已經遍歷,如果存在並且沒有遍歷,則把root指向右子樹;否則,結點出棧,並且把結點的右子樹遍歷標志出棧;
- 重復2-4直到棧空或者root不存在。
這是第一個一下想到的思路,可以看到用了兩個棧作為額外的空間,復雜度不是很好,並且在leetcode上提交后,運行時間感覺也不甚理想,有沒有更好的方法呢?
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def postorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
ret = []
stack = []
flag = []
while root or stack:
while root:
stack.append(root)
flag.append(0)
root = root.left
if stack:
top = stack[-1]
if top.right and not flag[-1]:
flag[-1] = 1
root = top.right
else:
flag.pop()
ret.append(stack.pop().val)
return ret
感覺在學校時接觸的第一門語言是C,數據結構也是基於C學的,導致第一印象總是往上面靠,寫出來的代碼不是很Pythonic,下面是一個我覺得更好的,代碼更少,也更容易理解的方法。
思路二:
后續遍歷根結點,先遍歷左子樹,然后遍歷右子樹,此時反過來考慮:先遍歷根結點,然后遍歷右子樹,最后是左子樹,這樣就可以轉化為和先序遍歷一個類型了,最后只把遍歷結果逆序輸出就ok了,而先序遍歷是之前寫過並且比較好理解的。
- 使用棧存儲結點;
- 當結點存在或者棧不為空,判斷結點;
- 當結點存在,結點值保存,結點入棧,並將指針指向結點的右子樹;
- 當棧不為空,結點出棧,並將指針指向左子樹;
- 重復2-4直到結果產生;
- 逆序輸出結果,利用Python列表的-1.
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def postorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
ret = []
stack = []
while root or stack:
while root:
ret.append(root.val)
stack.append(root)
root = root.right
if stack:
top = stack.pop()
root = top.left
return ret[::-1]