原题链接在这里:https://leetcode.com/problems/binary-tree-preorder-traversal/
虽然原题要求不让用recursion,但还是试了一下。一试发现自己的recursion真心无语。
Method 1 是Recursion,学到的新方法就是若是要在recursion中维护一个生成的变量,可以再造一个函数,然后把这个要维护的变量当成argument放在新函数中,新函数设计成recursive形式。还有就是新的函数可以设计成 return void的形式,比较好思考。
Time O(n), Space O(logn). 无论是recursion 还是 iteration, 占用空间都是与树的高度成正比的。
AC Java:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
// Method 1: Recursion
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> ls = new ArrayList<Integer>();
preorderTraversal(root,ls);
return ls;
}
public void preorderTraversal(TreeNode root, List<Integer> ls) {
if(root == null){
return;
}
ls.add(root.val);
preorderTraversal(root.left, ls);
preorderTraversal(root.right, ls);
}
}
Method 2 是Iteration,维护一个stack,先压root,stack不空条件下每次循环, 先pop(), 然后压right child, 再压left child。如此保证了出栈的顺序是preorder。//Method 2: Iteration
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> ls = new ArrayList<Integer>();
if(root == null){
return ls;
}
Stack<TreeNode> stk = new Stack<TreeNode>();
stk.push(root);
while(!stk.empty()){
TreeNode tn = stk.pop();
ls.add(tn.val);
if(tn.right != null){
stk.push(tn.right);
}
if(tn.left != null){
stk.push(tn.left);
}
}
return ls;
}
进栈的顺序都不变,与Binary Tree Inorder Traversal不同在于加ls的地方不同。
//Method 3: Iteration
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> ls = new ArrayList<Integer>();
Stack<TreeNode> stk = new Stack<TreeNode>();
while(root!=null || !stk.empty()){
if(root != null){
ls.add(root.val);
stk.push(root);
root = root.left;
}else{
root = stk.pop();
root = root.right;
}
}
return ls;
}
Method 4: Morris Traversal
也是借鉴了Morris Traversal, 与Inorder Traversal 相似,唯一不同就是加ls的时机不同。
Time O(n), Space O(1).
//Method 4: Morris Traversal
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> ls = new ArrayList<Integer>();
TreeNode cur = root;
TreeNode pre = null;
while(cur != null){
if(cur.left == null){
ls.add(cur.val);
cur = cur.right;
}else{
pre = cur.left;
while(pre.right!=null && pre.right != cur){
pre = pre.right;
}
if(pre.right == null){
ls.add(cur.val);
pre.right = cur;
cur = cur.left;
}else{
pre.right = null;
cur = cur.right;
}
}
}
return ls;
}