LeetCode 94. Binary Tree Inorder Traversal

原题链接在这里:https://leetcode.com/problems/binary-tree-inorder-traversal/#

题目:

Given a binary tree, return the inorder traversal of its nodes' values.

For example:
Given binary tree [1,null,2,3],

   1
    \
     2
    /
   3

return [1,3,2].

Note: Recursive solution is trivial, could you do it iteratively?

题解:

类似Binary Tree Preorder TraversalBinary Tree Postorder Traversal.

可以分别采用Recursion, Iteration 和 Morris Traversal 三种方法。

Method 1: Recursion

Recursion是traversal时最容易想到,并且好写的方法。

Time Complexity: O(n). Space O(logn).

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> inorderTraversal(TreeNode root) {
12         List<Integer> ls = new ArrayList<Integer>();
13         inorderTraversal(root, ls);
14         return ls;
15     }
16    public void inorderTraversal(TreeNode root, List<Integer> ls){
17        if(root == null){
18            return;
19        }
20        inorderTraversal(root.left, ls);
21        ls.add(root.val);
22        inorderTraversal(root.right, ls);
23    }
24  }

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> inorderTraversal(TreeNode* root) {
15         vector<int> res;
16         inorder(root, res);
17         return res;
18     }
19     
20 private: 
21     void inorder(TreeNode* root, vector<int>& res){
22         if(!root){
23             return;
24         }
25         
26         inorder(root->left, res);
27         res.push_back(root->val);
28         inorder(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 inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
 9         res = []
10         self.dfs(root, res)
11         return res
12 
13     def dfs(self, root, res):
14         if not root:
15             return
16         self.dfs(root.left, res)
17         res.append(root.val)
18         self.dfs(root.right, res) 
19         

Method 2: Iteration + Stack

Iteration 时基本就是利用stack的特性体现出recursion的方法。压栈的顺序要注意,一直压left, 直到null, 再pop, 移动root到pop出来的right. 循环直到点为空并且stack也为空。

Time Complexity: O(n). Space O(logn).

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> inorderTraversal(TreeNode root) {
12         List<Integer> res = new ArrayList<Integer>();
13         if(root == null){
14             return res;
15         }
16         Stack<TreeNode> stk = new Stack<TreeNode>();
17         while(root != null || !stk.isEmpty()){
18             if(root != null){
19                 stk.push(root);
20                 root = root.left;
21             }else{
22                 TreeNode tn = stk.pop();
23                 res.add(tn.val);
24                 root = tn.right;
25             }
26         }
27         return res;
28     }
29 }

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> inorderTraversal(TreeNode* root) {
15         vector<int> res;
16         stack<TreeNode*> stk;
17         while(root || !stk.empty()){
18             if(root){
19                 stk.push(root);
20                 root = root->left;
21             }else{
22                 root = stk.top();
23                 stk.pop();
24                 res.push_back(root->val);
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 inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
 9         res = []
10         stk = []
11         while stk or root:
12             if root:
13                 stk.append(root)
14                 root = root.left
15             else:
16                 cur = stk.pop()
17                 res.append(cur.val)
18                 root = cur.right
19         return res

 Method 3:

Morris Traversal 算法,参见了Morris Traversal这篇文章。

Time Complexity: O(n). Space O(1).利用 constant space traverse.

基本思路就是:

1. 看当前点cur的left是否为null, 若是null, add当前节点, cur = cur.right.

2. cur.left 不为 null, 先在左子树中找到cur 的predecessor, 然后分两种情况考虑:

a. predecessor.right = null, 表明左子树还没遍历过。那么predecessor.right 指向 cur; cur = cur.left.

b. predecessor.right = cur, 表明左子树已经遍历完了。那么先add cur, 然后把predecessor.right 改回null, 恢复树的结构,然后cur = cur.right.

Note: 1. while()里的条件和下面的if()条件是相呼应的. e.g while()里若写a.next != null, 下面的if()里就应该写a.next 的先关特性。

2. 代码看起来是两个while循环嵌套,感觉是Time 是O(n*logn),其实每个边最多被访问2次,edge的上限是n-1,所以Time is O(n).

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> inorderTraversal(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                 //Left node is not null, find predcessor
21                 pre = cur.left;
22                 while(pre.right != null && pre.right != cur){
23                     pre = pre.right;
24                     
25                 }
26                 
27                 if(pre.right == null){
28                     pre.right = cur;
29                     cur = cur.left;
30                 }else{
31                     res.add(cur.val);
32                     pre.right = null;
33                     cur = cur.right;
34                 }
35             }
36         }
37         return res;
38     }
39 }

跟上Convert Binary Search Tree to Sorted Doubly Linked ListConvert BST to Greater Tree.

posted @ 2015-08-20 02:48  Dylan_Java_NYC  阅读(314)  评论(0编辑  收藏  举报