Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
一、题目描述:
给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历 。
示例 1:
输入:root = [1,null,2,3] 输出:[3,2,1] 示例 2:
输入:root = [] 输出:[] 示例 3:
输入:root = [1] 输出:[1]
提示:
树中节点的数目在范围 [0, 100] 内 -100 <= Node.val <= 100
进阶:递归算法很简单,你可以通过迭代算法完成吗?
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/bi… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
二、思路分析:
父节点在栈内会被访问两次,第一次从左子树出栈后访问父节点时,父节点不进行出栈,而是将右子树入栈,继续访问右子树。只有当右子树出栈后访问父节点时,父节点才会出栈。 所以要记录上一个出栈的节点,用来判断一个节点的右子树是否被访问过。具体思路如下
- 找到最左下方节点并将路径上的节点入栈直到node.left为空
- 判断栈顶(最左下方节点)node.right是否为空,不为空则以node.right为起始节点继续【1】的操作
- 如果没有右节点/右节点已被访问过,则弹出栈顶元素,并记录当前弹出的节点
三、AC 代码:
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
Deque<TreeNode> stack = new ArrayDeque<>();
TreeNode curNode = root; // 标志当前节点(当节点进行入栈时不为空,节点为空时标志该出栈)
TreeNode lastPopNode = null;// 记录上一个出栈的node
while (!stack.isEmpty() || curNode != null) {
if (curNode != null) {
// 延左子树向下寻找【1】
stack.push(curNode);
curNode = curNode.left;
} else {
// curNode == null 表示左子树遍历到头/正在出栈
curNode = stack.peek(); // 先不弹出,可能是第一次访问
if (curNode.right == null || curNode.right == lastPopNode) {
// 没有右子树/右子树已访问过【3】
stack.pop(); // 可以弹出
lastPopNode = curNode;
result.add(curNode.val);
curNode = null; // 注意要把curNode置空
} else {
// 有右子树且右子树未被访问过【2】
curNode = curNode.right; // 进入右子树
}
}
}
return result;
}
}
四、总结:
三种遍历算法都做了一遍了,下面总结一下前中后序遍历顺序,如下:
前序遍历:中左右 中序遍历:左中右 后序遍历:左右中
掘友们,解题不易,留下个赞或评论再走吧!谢啦~ 💐