144. Binary Tree Preorder Traversal
题目:
连接: http://leetcode.com/problems/binary-tree-preorder-traversal/
题解:
二叉树先序遍历, root -> left -> right。使用一个栈来维护已经访问过的节点。当root不为空时,当前节点入栈,输出节点值,继续向左子树遍历。当root为空,从栈中弹出节点,向右子树进行遍历。
Iterative:
Time Complexity - O(n), Space Complexity - O(n)。
public class Solution { public ArrayList<Integer> preorderTraversal(TreeNode root) { ArrayList<Integer> result = new ArrayList<Integer>(); if(root == null) return result; Stack<TreeNode> stack = new Stack<TreeNode>(); while(root != null || !stack.isEmpty()){ if(root != null){ stack.push(root); result.add(root.val); root = root.left; } else { root = stack.pop(); root = root.right; } } return result; } }
Recursive:
Time Complexity - O(n), Space Complexity - O(n)。
public class Solution { public ArrayList<Integer> preorderTraversal(TreeNode root) { ArrayList<Integer> result = new ArrayList<Integer>(); if(root == null) return result; helper(result, root); return result; } private void helper(ArrayList<Integer> result, TreeNode root){ if(root == null) return; result.add(root.val); helper(result, root.left); helper(result, root.right); } }
Update:
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ public class Solution { public List<Integer> preorderTraversal(TreeNode root) { List<Integer> res = new ArrayList<>(); if(root == null) return res; Stack<TreeNode> stack = new Stack<>(); stack.push(root); while(!stack.isEmpty()) { root = stack.pop(); if(root != null) { res.add(root.val); if(root.right != null) stack.push(root.right); if(root.left != null) stack.push(root.left); } } return res; } }
Morris-Travel: 待定。
二刷:
Java:
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ public class Solution { public List<Integer> preorderTraversal(TreeNode root) { List<Integer> res = new ArrayList<>(); if (root == null) { return res; } Stack<TreeNode> stack = new Stack<>(); while (root != null || !stack.isEmpty()) { if (root != null) { res.add(root.val); stack.push(root.right); root = root.left; } else { root = stack.pop(); } } return res; } }
三刷:
Java:
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ public class Solution { public List<Integer> preorderTraversal(TreeNode root) { List<Integer> res = new ArrayList<>(); Stack<TreeNode> stack = new Stack<>(); while (!stack.isEmpty() || root != null) { if (root != null) { res.add(root.val); stack.push(root.right); root = root.left; } else { root = stack.pop(); } } return res; } }
Recursive:
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ public class Solution { public List<Integer> preorderTraversal(TreeNode root) { List<Integer> res = new ArrayList<>(); preorderTraversal(res, root); return res; } private void preorderTraversal(List<Integer> res, TreeNode root) { if (root == null) return; res.add(root.val); preorderTraversal(res, root.left); preorderTraversal(res, root.right); } }
三刷:
Java:
Iterative with a stack:
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ public class Solution { public List<Integer> preorderTraversal(TreeNode root) { List<Integer> res = new ArrayList<>(); TreeNode node = root; Stack<TreeNode> stack = new Stack<>(); while (node != null || !stack.isEmpty()) { if (node != null) { res.add(node.val); stack.push(node); node = node.left; } else { node = stack.pop(); node = node.right; } } return res; } }
Recursive:
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ public class Solution { public List<Integer> preorderTraversal(TreeNode root) { List<Integer> res = new ArrayList<>(); preorderTraversal(res, root); return res; } private void preorderTraversal(List<Integer> res, TreeNode root) { if (root == null) return; res.add(root.val); preorderTraversal(res, root.left); preorderTraversal(res, root.right); } }
Morris traversal:
使用了类似in-order Morris Traversal类似的代码。在可以改变树结构的情况下,使用空的右子树来连接到父节点,最后再还原树结构。下面详述一下步骤:
- 在当前node非空的情况下对树进行遍历。仍然是先判断左子树是否为空,假如为空,则我们将当前节点node.val加入到结果集里,继续向右遍历树
- 否则左子树非空,这时我们向左子树里查找当前节点node的predecessor,简称prev,即左子树中最右端的元素。依然是两种情况:
- 当prev.right为空时,我们第一次访问此节点,这时把prev.right设置为当前节点node,然后把当前节点node.val加入到结果集里,向左遍历树
- 否则prev.right = 为当前node,说明我们是第二次访问这个节点,这时要做一个树的还原操作,也就是断开prev和node的连接,即prev.right = null,然后向右遍历树。这时候因为我们的当前节点node已经被处理过了,所以不要再次处理node.val
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ public class Solution { public List<Integer> preorderTraversal(TreeNode root) { List<Integer> res = new ArrayList<>(); TreeNode node = root, prev = null; while (node != null) { if (node.left == null) { res.add(node.val); node = node.right; } else { prev = node.left; while (prev.right != null && prev.right != node) { prev = prev.right; } if (prev.right == null) { prev.right = node; res.add(node.val); node = node.left; } else { prev.right = null; node = node.right; } } } return res; } }
Update:
简化了一下,反而比较古怪,不易理解。
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ public class Solution { public List<Integer> preorderTraversal(TreeNode root) { List<Integer> res = new ArrayList<>(); TreeNode node = root, prev = null; while (node != null) { prev = node.left; while (prev != null && prev.right != null && prev.right != node) { prev = prev.right; } if (prev != null && prev.right == null) { prev.right = node; res.add(node.val); node = node.left; } else { if (prev != null) prev.right = null; else res.add(node.val); node = node.right; } } return res; } }
Reference:
https://leetcode.com/discuss/9734/accepted-code-explaination-with-algo
https://leetcode.com/discuss/5331/whats-the-simplest-and-cleanest-answer
https://leetcode.com/discuss/23326/very-simple-iterative-python-solution
https://leetcode.com/discuss/19798/accepted-iterative-solution-in-java-using-stack
https://leetcode.com/discuss/32904/3-different-solutions
https://leetcode.com/discuss/49926/easy-read-java-solutions-for-both-iterative-recursive-300ms
https://leetcode.com/discuss/46894/java-solution-both-recursion-and-iteration