LeetCode 144. Binary Tree Preorder Traversal
原题链接在这里:https://leetcode.com/problems/binary-tree-preorder-traversal/
题目:
Given a binary tree, return the preorder traversal of its nodes' values.
For example:
Given binary tree {1,#,2,3}
,
1 \ 2 / 3
return [1,2,3]
.
Note: Recursive solution is trivial, could you do it iteratively?
题解:
Method 1 是Recursion.
Time Complexity: O(n), 每个点访问了一遍. Space: O(logn), stack space.
AC Java:
1 /** 2 * Definition for a binary tree node. 3 * public class TreeNode { 4 * int val; 5 * TreeNode left; 6 * TreeNode right; 7 * TreeNode(int x) { val = x; } 8 * } 9 */ 10 public class Solution { 11 // Method 1: Recursion 12 public List<Integer> preorderTraversal(TreeNode root) { 13 List<Integer> ls = new ArrayList<Integer>(); 14 preorderTraversal(root,ls); 15 return ls; 16 17 } 18 public void preorderTraversal(TreeNode root, List<Integer> ls) { 19 if(root == null){ 20 return; 21 } 22 ls.add(root.val); 23 preorderTraversal(root.left, ls); 24 preorderTraversal(root.right, ls); 25 } 26 }
AC C++:
1 /** 2 * Definition for a binary tree node. 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode() : val(0), left(nullptr), right(nullptr) {} 8 * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 9 * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 10 * }; 11 */ 12 class Solution { 13 public: 14 vector<int> preorderTraversal(TreeNode* root) { 15 vector<int> res; 16 dfs(root, res); 17 return res; 18 } 19 20 private: 21 void dfs(TreeNode* root, vector<int>& res){ 22 if(!root){ 23 return; 24 } 25 26 res.push_back(root->val); 27 dfs(root->left, res); 28 dfs(root->right, res); 29 } 30 };
AC Python:
1 # Definition for a binary tree node. 2 # class TreeNode: 3 # def __init__(self, val=0, left=None, right=None): 4 # self.val = val 5 # self.left = left 6 # self.right = right 7 class Solution: 8 def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]: 9 res = [] 10 self.dfs(root, res) 11 return res 12 def dfs(self, root, res): 13 if not root: 14 return 15 res.append(root.val) 16 self.dfs(root.left, res) 17 self.dfs(root.right, res)
Method 2 是Iteration,维护一个stack,先压root,stack不空条件下每次循环, 先pop(), 然后压right child, 再压left child. 如此保证了出栈的顺序是preorder.
Time Complexity: O(n). Space: O(logn).
AC Java:
1 //Method 2: Iteration 2 public List<Integer> preorderTraversal(TreeNode root) { 3 List<Integer> ls = new ArrayList<Integer>(); 4 if(root == null){ 5 return ls; 6 } 7 Stack<TreeNode> stk = new Stack<TreeNode>(); 8 stk.push(root); 9 while(!stk.isEmpty()){ 10 TreeNode tn = stk.pop(); 11 ls.add(tn.val); 12 if(tn.right != null){ 13 stk.push(tn.right); 14 } 15 if(tn.left != null){ 16 stk.push(tn.left); 17 } 18 } 19 return ls; 20 }
Method 3 : 上面的方法是对的,但是为了统一记忆Preorder, Inorder, Postorder, 改写成了下面的Method 3.
进栈的顺序都不变,与Binary Tree Inorder Traversal不同在于加ls的地方不同.
Time Complexity: O(n). Space: O(logn).
AC Java:
1 //Method 3: Iteration 2 public List<Integer> preorderTraversal(TreeNode root) { 3 List<Integer> ls = new ArrayList<Integer>(); 4 Stack<TreeNode> stk = new Stack<TreeNode>(); 5 while(root!=null || !stk.isEmpty()){ 6 if(root != null){ 7 ls.add(root.val); 8 stk.push(root); 9 root = root.left; 10 }else{ 11 root = stk.pop(); 12 root = root.right; 13 } 14 } 15 return ls; 16 }
AC C++:
1 /** 2 * Definition for a binary tree node. 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode() : val(0), left(nullptr), right(nullptr) {} 8 * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 9 * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 10 * }; 11 */ 12 class Solution { 13 public: 14 vector<int> preorderTraversal(TreeNode* root) { 15 vector<int> res; 16 stack<TreeNode*> stk; 17 while(root || !stk.empty()){ 18 if(root){ 19 res.push_back(root->val); 20 stk.push(root); 21 root = root->left; 22 }else{ 23 root = stk.top(); 24 stk.pop(); 25 root = root->right; 26 } 27 } 28 29 return res; 30 } 31 };
AC Python:
1 # Definition for a binary tree node. 2 # class TreeNode: 3 # def __init__(self, val=0, left=None, right=None): 4 # self.val = val 5 # self.left = left 6 # self.right = right 7 class Solution: 8 def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]: 9 res, stk = [], [] 10 while root or stk: 11 if root: 12 res.append(root.val) 13 stk.append(root) 14 root = root.left 15 else: 16 root = stk.pop().right 17 return res
Method 4: Morris Traversal
也是借鉴了Morris Traversal, 与Binary Tree Inorder Traversal相似,唯一不同就是加ls的时机不同。
Time Complexity: O(n). Space: O(1).
AC Java:
1 /** 2 * Definition for a binary tree node. 3 * public class TreeNode { 4 * int val; 5 * TreeNode left; 6 * TreeNode right; 7 * TreeNode(int x) { val = x; } 8 * } 9 */ 10 public class Solution { 11 public List<Integer> preorderTraversal(TreeNode root) { 12 List<Integer> res = new ArrayList<Integer>(); 13 TreeNode cur = root; 14 TreeNode pre = null; 15 while(cur != null){ 16 if(cur.left == null){ 17 res.add(cur.val); 18 cur = cur.right; 19 }else{ 20 pre = cur.left; 21 while(pre.right != null && pre.right != cur){ 22 pre = pre.right; 23 } 24 25 if(pre.right == null){ 26 res.add(cur.val); 27 pre.right = cur; 28 cur = cur.left; 29 }else{ 30 pre.right = null; 31 cur = cur.right; 32 } 33 } 34 } 35 return res; 36 } 37 }
类似Binary Tree Inorder Traversal, Binary Tree Postorder Traversal.
跟上Verify Preorder Sequence in Binary Search Tree, Subtree of Another Tree, N-ary Tree Preorder Traversal.