leetcode - 二叉樹筆記

1.前序/中序/後序/層序遍歷(非遞歸版本)

遞歸版本見註釋部分代碼

迭代方法使用棧。當前訪問的節點一定是棧頂的節點(都是先將根節點入棧),先取出,再按照遍歷順序將其他節點入棧。

根據下面這個模板來思考:

while 棧非空 or p非空:
    if p 非空:
           xxxxxxx
    else:
           xxxxxxx

①前序遍歷

這個方法是先讀取根節點結果,右子樹、左子樹分別入棧,出棧輸出結果則是根->左->右

class Solution:
    # def __init__(self):
    #     self.res = []
    def preorderTraversal(self, root: TreeNode) -> List[int]:
        # 遞歸
        #  if root: 
        #     self.res.append(root.val)
        #     self.preorderTraversal(root.left)
        #     self.preorderTraversal(root.right)
        # return self.res
            
        # 棧
        res = []
        if not root: return res
        s = [root]
        while s:
            node = s.pop()
            res.append(node.val)
            if node.right: s.append(node.right)
            if node.left: stack.append(node.left)            
        return res

② 中序遍歷
只對根節點做出入棧的處理。根先入棧,遍歷左子樹,根出棧,遍歷右子樹,則輸出結果爲左->根->右。

class Solution:
    # def __init__(self):
    #     self.res = []
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        # if root:
        #     self.inorderTraversal(root.left)
        #     self.res.append(root.val)
        #     self.inorderTraversal(root.right)
        # return self.res
        
        # 棧
        res = [] 
        if not root :return res
        s = []
        while s or root:
            if root:
                s.append(root)
                root = root.left
            else:
                root = s.pop()
                res.append(root.val)
                root = root.right
        return res

③後序遍歷

巧妙借用前序的思想,先讀取根節點結果,左子樹、右子樹依次入棧,則輸出爲根->右->左,最後將輸出逆序就能生成正確的後序輸出:左->右->根。

class Solution:
    # def __init__(self):
    #     self.res = []
    def postorderTraversal(self, root):
        # 遞歸
        # if root:
        #     self.postorderTraversal(root.left)
        #     self.postorderTraversal(root.right)
        #     self.res.append(root.val)
        # return self.res
        
        # 棧
        res = []
        if not root: return res
        s = [root]
        while s:
            node = s.pop()
            res.append(node.val)
            if node.left: s.append(node.left)
            if node.right: s.append(node.right)
        return res[::-1]

④ 層序遍歷

用隊列的方法,每次訪問隊首節點,並將其左、右子樹入隊。

class Solution:
    def levelOrder(self, root: TreeNode) -> List[List[int]]:
        res = []
        if not root: return res
        q = [root]
        while q:
            level = []
            n = len(q)
            for i in range(n):
                level.append(q[i].val)
                if q[i].left: q.append(q[i].left)
                if q[i].right: q.append(q[i].right)
            q = q[n:]
            res.append(level)
            level = []
        return res		       

2.遞歸方法中的自頂向下 / 自底向上

舉例:求二叉樹最大深度

① 自頂向下( 通過函數傳值的方法,從頂層傳到底層)

class Solution:
    def _maxDepth(self, root, depth):
        if not root: return depth-1
        l_depth = self._maxDepth(root.left,depth+1)
        r_depth = self._maxDepth(root.right,depth+1)
        return max(l_depth,r_depth)
    def maxDepth(self, root: TreeNode) -> int:
        if not root: return 0
        return self._maxDepth(root,1)

② 自底向上

class Solution:
    def maxDepth(self, root: TreeNode) -> int:
        if not root: return 0
        l_depth = self.maxDepth(root.left)
        r_depth = self.maxDepth(root.right)
        return max(l_depth,r_depth)+1
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章