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 Traversal, Binary 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 List, Convert BST to Greater Tree.