leetcode-145:二叉树的后序遍历

简介: leetcode-145:二叉树的后序遍历

题目

题目链接

给定一个二叉树,返回它的 后序 遍历。

示例:

输入: [1,null,2,3]  
   1
    \
     2
    /
   3 
输出: [3,2,1]

进阶: 递归算法很简单,你可以通过迭代算法完成吗?

解题

参考链接

方法一:递归

python解法

# 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: TreeNode) -> List[int]:
        def postorder(root):
            if not root:
                return 
            postorder(root.left)
            postorder(root.right)
            res.append(root.val)
        res = []
        postorder(root)
        return res

c++解法

class Solution {
public:
    void postorder(TreeNode* root,vector<int>& res){
        if(!root) return;
        postorder(root->left,res);
        postorder(root->right,res);
        res.push_back(root->val);
    }
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> res;
        postorder(root,res);
        return res;
    }
};

方法二:迭代

模板解法:

继续按照上面的思想,这次我们反着思考,节点 cur 先到达最右端的叶子节点并将路径上的节点入栈;

然后每次从栈中弹出一个元素后,cur 到达它的左孩子,并将左孩子看作 cur 继续执行上面的步骤。

最后将结果反向输出即可。参考代码如下:

python解法

# 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: TreeNode) -> List[int]:
        if not root:
            return []
        cur,stack,res = root,[],[]
        while cur or stack:
            while cur:
                res.append(cur.val)
                stack.append(cur)
                cur = cur.right
            cur = stack.pop()
            cur = cur.left
        return res[::-1]

然而,后序遍历采用模板解法并没有按照真实的栈操作,而是利用了结果的特点反向输出,不免显得技术含量不足。

因此掌握标准的栈操作解法是必要的。

c++解法

class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        if(!root) return {};
        vector<int> res;
        stack<TreeNode*> stack;
        TreeNode* cur=root;
        while(!stack.empty()||cur){
            while(cur){
                res.push_back(cur->val);
                stack.push(cur);
                cur=cur->right;
            }
            cur=stack.top();
            stack.pop();
            cur=cur->left;
        }
        reverse(res.begin(),res.end());
        return res;
    }
};

java解法

调用Collections里面的reverse

class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> res=new LinkedList<>();
        TreeNode cur=root;
        Stack<TreeNode> st=new Stack<>();
        while(!st.isEmpty()||cur!=null){
            while(cur!=null){
                res.add(cur.val);
                st.push(cur);
                cur=cur.right;
            }
            cur=st.pop();
            cur=cur.left;
        }
        Collections.reverse(res);
        return res;
    }
}

常规解法:

python解法

# 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: TreeNode) -> List[int]:
        if not root:
            return []
        stack = []
        res = []
        cur = root
        prev = None
        while stack or cur:
            while cur:
                stack.append(cur)
                cur = cur.left
            cur = stack.pop()
            if not cur.right or cur.right==prev:
                res.append(cur.val)
                prev = cur
                cur = None # 防止进入上面的while
            else:
                stack.append(cur)# 还是要加入到stack,这样才能回到上面的if 语句中去
                cur = cur.right
        return res

c++解法

class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        if(!root) return {};
        vector<int> res;
        stack<TreeNode*> stack;
        TreeNode* cur=root;
        TreeNode* prev=nullptr;
        while(!stack.empty()||cur){
            while(cur){
               stack.push(cur);
               cur=cur->left;
            }
            cur=stack.top();
            stack.pop();
            if(!cur->right||cur->right==prev){
                res.push_back(cur->val);
                prev=cur;
                cur=nullptr;
            }
            else{
                stack.push(cur);
                cur=cur->right;
            }
        }
        return res;
    }
};

用prev来标记节点,如果右子节点之前访问过了或者右子节点不存在,那么就把该节点(第三次访问)加入到列表中。

相关文章
|
1月前
【LeetCode 31】104.二叉树的最大深度
【LeetCode 31】104.二叉树的最大深度
19 2
|
1月前
【LeetCode 29】226.反转二叉树
【LeetCode 29】226.反转二叉树
16 2
|
1月前
【LeetCode 28】102.二叉树的层序遍历
【LeetCode 28】102.二叉树的层序遍历
15 2
|
1月前
【LeetCode 43】236.二叉树的最近公共祖先
【LeetCode 43】236.二叉树的最近公共祖先
19 0
|
1月前
【LeetCode 38】617.合并二叉树
【LeetCode 38】617.合并二叉树
14 0
|
1月前
【LeetCode 37】106.从中序与后序遍历构造二叉树
【LeetCode 37】106.从中序与后序遍历构造二叉树
17 0
|
1月前
【LeetCode 34】257.二叉树的所有路径
【LeetCode 34】257.二叉树的所有路径
17 0
|
1月前
【LeetCode 32】111.二叉树的最小深度
【LeetCode 32】111.二叉树的最小深度
16 0
|
3月前
|
存储 算法
二叉树进阶-学会层序遍历助你一次刷完leetcode10道题
文章深入探讨了二叉树的层序遍历方法,并展示了如何通过队列实现层序遍历的算法逻辑,同时指出掌握层序遍历技巧可以帮助解决LeetCode上的多道相关题目。
二叉树进阶-学会层序遍历助你一次刷完leetcode10道题
|
3月前
|
算法 Java
LeetCode第94题二叉树的中序遍历
文章介绍了LeetCode第94题"二叉树的中序遍历"的解法,使用递归实现了中序遍历的过程,遵循了"左根右"的遍历顺序,并提供了清晰的Java代码实现。
LeetCode第94题二叉树的中序遍历