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 TraversalBinary Tree Postorder Traversal.

跟上Verify Preorder Sequence in Binary Search TreeSubtree of Another TreeN-ary Tree Preorder Traversal.

posted @ 2015-08-19 09:15  Dylan_Java_NYC  阅读(421)  评论(0编辑  收藏  举报