• 【LeetCode】145. 二叉树的后序遍历 [ 左子树 右子树 根结点]


    题目链接


    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

    Python3

    方法一: 递归 ⟮ O ( n ) ⟯ \lgroup O(n) \rgroup O(n)⟯

    在这里插入图片描述

    # Definition for a binary tree node.
    # class TreeNode:
    #     def __init__(self, val=0, left=None, right=None):
    #         self.val = val
    #         self.left = left
    #         self.right = right
    class Solution:
        def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
            """后序遍历 [ 左子树 右子树 根结点 ] 递归 """
            def postorder(node):
                if not node:
                    return 
                postorder(node.left) # 左子树 
                postorder(node.right) # 右子树
                ans.append(node.val)  # 根结点
    
            ans = []
            postorder(root)
            return ans
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    方法二: 迭代 ⟮ O ( n ) ⟯ \lgroup O(n) \rgroup O(n)⟯

    # Definition for a binary tree node.
    # class TreeNode:
    #     def __init__(self, val=0, left=None, right=None):
    #         self.val = val
    #         self.left = left
    #         self.right = right
    class Solution:
        def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
            """后序遍历 [左子树  右子树  根]  迭代"""
    
            ans = []
            stack = []
            cur = root
            pre = None
            while cur or stack:
                while cur:
                    stack.append(cur)
                    cur = cur.left # 左
    
                cur = stack.pop()
                if not cur.right or cur.right == pre: ## 右边 已遍历完
                    ans.append(cur.val) # 根 
                    pre = cur 
                    cur = None 
                else:
                    stack.append(cur)
                    cur = cur.right  # 右
            return ans
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    在这里插入图片描述

    方法三: Morris ⟮ O ( n ) 、 O ( 1 ) ⟯ \lgroup O(n)、O(1) \rgroup O(n)O(1)⟯

    在这里插入图片描述

    写法一
    # Definition for a binary tree node.
    # class TreeNode:
    #     def __init__(self, val=0, left=None, right=None):
    #         self.val = val
    #         self.left = left
    #         self.right = right
    class Solution:
        def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
            """ 后序遍历 [ 左子树 右子树 根 ]  Morris  O(N) O(1)"""
            ### 写法一  根 右 左   反转结果列表  
            # 根据 前序遍历 修改
            ans = []
            cur, pre = root, None 
            while cur:
                if not cur.right:
                    ans.append(cur.val)  ##
                    cur = cur.left
    
                # 有右孩子
                else:
                    # 找 pre 
                    pre = cur.right 
                    while pre.left and pre.left != cur:
                        pre = pre.left  
                    if not pre.left: ## 找到 mostleft
                        pre.left = cur
                        ans.append(cur.val)  ## 
                        cur = cur.right
                    else:
                        pre.left = None 
                        cur = cur.left
            return ans[::-1]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    写法二
    # Definition for a binary tree node.
    # class TreeNode:
    #     def __init__(self, val=0, left=None, right=None):
    #         self.val = val
    #         self.left = left
    #         self.right = right
    class Solution:
        def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
            """ 后序遍历 [ 左子树 右子树 根 ]  Morris  O(N) O(1)"""
            ## 需要 增加 一个 反转模块
            def addPath(node: TreeNode):
                count = 0
                while node:
                    count += 1
                    ans.append(node.val)
                    node = node.right
                i, j = len(ans) - count, len(ans) - 1
                while i < j:
                    ans[i], ans[j] = ans[j], ans[i]
                    i += 1
                    j -= 1
            ### 
            ans = []
            cur, pre = root, None 
            while cur:
                if not cur.left:
                    cur = cur.right 
    
                # 有左孩子
                else:
                    # 找 pre 
                    pre = cur.left 
                    while pre.right and pre.right != cur:
                        pre = pre.right  
                    if not pre.right:
                        pre.right = cur
                        cur = cur.left 
                    else:
                        pre.right = None 
                        addPath(cur.left) ## 
                        cur = cur.right 
            addPath(root)  ## 
            return ans 
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    C++

    方法一: 递归 ⟮ O ( n ) ⟯ \lgroup O(n) \rgroup O(n)⟯

    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
     *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
     *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
     * };
     */
    class Solution {
    public:
        // 子模块
        void postorder(TreeNode* node, vector<int> &ans){
            if (node == nullptr){
                return;
            }
            postorder(node->left, ans);
            postorder(node->right, ans);
            ans.emplace_back(node->val);
        }
    
        // 主模块
        vector<int> postorderTraversal(TreeNode* root) {
            vector<int> ans;
            postorder(root, ans);
            return ans;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    方法二: 迭代 ⟮ O ( n ) ⟯ \lgroup O(n) \rgroup O(n)⟯

    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
     *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
     *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
     * };
     */
    class Solution {
    public:
        vector<int> postorderTraversal(TreeNode* root) {
            vector<int> ans;
            stack<TreeNode*>stk;
            TreeNode* cur = root;
            TreeNode* pre = nullptr;
    
            while (cur != nullptr || !stk.empty()){
                while (cur != nullptr){
                    stk.emplace(cur);
                    cur = cur->left;
                }
    
                cur = stk.top();
                stk.pop();
                if (cur->right == nullptr || cur->right == pre){// 右子树 遍历完,处理根结点
                    ans.emplace_back(cur->val);
                    pre = cur;
                    cur = nullptr;
                }
                else{// 右子树
                    stk.emplace(cur);
                    cur = cur->right;
                }
            }
            return ans;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    方法三: Morris ⟮ O ( n ) 、 O ( 1 ) ⟯ \lgroup O(n)、O(1) \rgroup O(n)O(1)⟯

    写法一
    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
     *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
     *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
     * };
     */
    class Solution {
    public:
        vector<int> postorderTraversal(TreeNode* root) {
            vector<int> ans;
            TreeNode* cur = root;
            TreeNode* pre = nullptr;
    
            while (cur != nullptr){
                if (cur->right == nullptr){
                    ans.emplace_back(cur->val);
                    cur = cur->left;
                }
                else{
                    // 找 pre 
                    pre = cur->right;
                    while (pre->left != nullptr && pre->left != cur){
                        pre = pre->left;
                    }
                    if (pre->left == nullptr){
                        pre->left = cur;
                        ans.emplace_back(cur->val);
                        cur = cur->right;
                    }
                    else{
                        pre->left = nullptr;
                        cur = cur->left;
                    }
                }
            }
    
            reverse(ans.begin(), ans.end()); // 该函数为 void ,不能直接返回
            return ans;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    写法二
    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
     *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
     *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
     * };
     */
    class Solution {
    public:
        // 子模块
        void addPath(TreeNode* node, vector<int> &ans){
            int count = 0;
            while (node != nullptr){ //  当前结点左结点(代入 cur->left)  到  前驱结点 间的结点
                count += 1;
                ans.emplace_back(node->val);
                node = node->right;
            }
            reverse(ans.end() - count, ans.end());  // 这段 结点要逆序输出
        }
    
        // 主模块
        vector<int> postorderTraversal(TreeNode* root) {
            vector<int> ans;
            TreeNode* cur = root;
            TreeNode* pre = nullptr;
    
            while (cur != nullptr){
                if (cur->left == nullptr){
                    cur = cur->right;
                }
                else{
                    //找 pre 
                    pre = cur->left;
                    while (pre->right != nullptr && pre->right != cur){
                        pre = pre->right;
                    }
                    if (pre->right == nullptr){
                        pre->right = cur;
                        cur = cur->left;
                    }
                    else{
                        pre->right  = nullptr;
                        addPath(cur->left, ans);
                        cur = cur->right;
                    }
                }
    
            }
            addPath(root, ans);
            return ans;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    之前版本

    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
     *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
     *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
     * };
     */
    class Solution {
    public:
        // 子模块
        void addPath(TreeNode* node, vector<int> &ans){
            int count = 0;
            while (node != nullptr){
                count += 1;
                ans.emplace_back(node->val);
                node = node->right;
            }
    
            int i = ans.size() - count, j = ans.size() - 1;
            while (i < j){
                swap(ans[i], ans[j]);
                i += 1;
                j -= 1;
            }
    
        }
    
        // 主模块
        vector<int> postorderTraversal(TreeNode* root) {
            vector<int> ans;
            TreeNode* cur = root;
            TreeNode* pre = nullptr;
    
            while (cur != nullptr){
                if (cur->left == nullptr){
                    cur = cur->right;
                }
                else{
                    //找 pre 
                    pre = cur->left;
                    while (pre->right != nullptr && pre->right != cur){
                        pre = pre->right;
                    }
                    if (pre->right == nullptr){
                        pre->right = cur;
                        cur = cur->left;
                    }
                    else{
                        pre->right  = nullptr;
                        addPath(cur->left, ans);
                        cur = cur->right;
                    }
                }
    
            }
            addPath(root, ans);
            return ans;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
  • 相关阅读:
    Arthas之类操作
    PDF文件太大怎么办?三招教会你PDF文件压缩
    编程题练习@9-13
    程序员自由创业周记#13:第一桶金
    学习 Rust 的第十天:枚举和模式匹配
    十个你要知道的测试小知识
    Java基础入门·File类的使用
    Pandas缺失值inf与nan处理实践
    ArrayUtils使用
    CMake中option和cmake_dependent_option的使用
  • 原文地址:https://blog.csdn.net/weixin_46034116/article/details/133962556