文章目录
题目:
给定一个二叉树,返回它的 后序 遍历。
示例:
输入: [1,null,2,3]
1
\
2
/
3
输出: [3,2,1]
进阶: 递归算法很简单,你可以通过迭代算法完成吗?
解法1:递归
public List<Integer> postorderTraversal(TreeNode root) {
ArrayList<Integer> result = new ArrayList<>();
recursive(result,root);
return result;
}
private void recursive(ArrayList<Integer> result, TreeNode root) {
if (root==null)return;
recursive(result,root.left);
recursive(result,root.right);
result.add(root.val);
}
时间复杂度:On
空间复杂度:On
解法2:stack
/**
* 思路:
* 关键:记录右侧节点是否走过 走到极左 判断右侧节点
*
* 先走到极左
* 之后判断是否有右侧节点
* 没有,加入结果集,记录当前节点为右子树,用来判断是否走过右侧,root赋值为null
* 有,root赋值为root.right
*/
public List<Integer> postorderTraversal(TreeNode root) {
ArrayList<Integer> result = new ArrayList<>();
ArrayDeque<TreeNode> stack = new ArrayDeque<>();
//保证右侧不会走第二遍
TreeNode right_record=null;
while (!stack.isEmpty()||root!=null){
while (root!=null){
stack.push(root);
root=root.left;
}
root=stack.pop();
if (root.right==null||root.right==right_record) {
result.add(root.val);
//记录右子树,用来标记是否走过右侧
right_record=root;
root=null;
}else {
stack.push(root);
root=root.right;
}
}
return result;
}
时间复杂度:On
空间复杂度:On
解法3:Morris
/**
* https://leetcode.com/problems/binary-tree-postorder-traversal/discuss/45648/Three-ways-of-Iterative-PostOrder-Traversing.-Easy-Explanation!
*/
public static void main(String[] args) {
TreeNode t1 = new TreeNode(1);
TreeNode t2 = new TreeNode(2);
TreeNode t3 = new TreeNode(3);
TreeNode t4 = new TreeNode(4);
TreeNode t5 = new TreeNode(5);
TreeNode t6 = new TreeNode(6);
t1.left=t2;
t1.right=t3;
t2.right=t4;
t4.left=t5;
t4.right=t6;
postorderTraversal(t1);
}
static class TreeNode{
int val;
TreeNode left,right;
public TreeNode(int val){
this.val=val;
}
public TreeNode(TreeNode left, TreeNode right, int val){
this.left=left;
this.right=right;
this.val=val;
}
}
public static List<Integer> postorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<Integer>();
TreeNode dummy = new TreeNode(-1);
TreeNode pre = null;
dummy.left = root;
root = dummy;
while (root!=null){
if (root.left!=null){
pre = root.left;
while(pre.right != null && pre.right != root)
pre=pre.right;
if(pre.right == null){
pre.right = root;
root = root.left;
} else{
TreeNode node = pre;
reverse(root.left,pre);
while(node != root.left){
result.add(node.val);
node = node.right;
}
result.add(node.val); // Print again since we are stopping at node=root.left
reverse(pre,root.left);
pre.right = null;
root = root.right;
}
}else {
root=root.right;
}
}
return result;
}
public static void reverse(TreeNode rootLeft, TreeNode pre){
if(rootLeft == pre)
return;
TreeNode prev = rootLeft, node = rootLeft.right;
while(prev != pre){
TreeNode next = node.right;
node.right = prev;
prev = node;
node = next;
}
}
时间复杂度:On
空间复杂度:On
解法4:颜色遍历
/**
* 思路:
* 颜色标记,0是没走过,1是走过
* 在栈中存放paris 0/1,node
* 如果当前节点是没走过,按照根右左的顺序加入栈中
*/
public List<Integer> postorderTraversal(TreeNode root) {
ArrayList<Integer> result = new ArrayList<>();
if (root==null)return result;
ArrayDeque<Pair<Integer,TreeNode>> stack = new ArrayDeque<>();
stack.push(new Pair<>(0,root));
while (!stack.isEmpty()){
Pair<Integer, TreeNode> pop = stack.pop();
if (pop.getKey()==0) {
stack.push(new Pair<>(1, pop.getValue()));
if (pop.getValue().right!=null) stack.push(new Pair<>(0, pop.getValue().right));
if (pop.getValue().left!=null) stack.push(new Pair<>(0, pop.getValue().left));
}else {
result.add(pop.getValue().val);
}
}
return result;
}
时间复杂度:On
空间复杂度:On