题目大意

https://leetcode.com/problems/binary-tree-inorder-traversal/description/

94. Binary Tree Inorder Traversal

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

Example:

Input: [1,null,2,3]
1
\
2
/
3 Output: [1,3,2]

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

解题思路

中序遍历:左根右

Approach 1: Recursive Approach 递归

The first method to solve this problem is using recursion. This is the classical method and is straightforward. We can define a helper function to implement recursion.

Python解法

class Solution(object):
def inorderTraversal(self, root): # 递归
"""
:type root: TreeNode
:rtype: List[int]
"""
if not root:
return []
return self.inorderTraversal(root.left) + [root.val] + self.inorderTraversal(root.right)

Java解法

class Solution {
public List < Integer > inorderTraversal(TreeNode root) {
List < Integer > res = new ArrayList < > ();
helper(root, res);
return res;
} public void helper(TreeNode root, List < Integer > res) {
if (root != null) {
if (root.left != null) {
helper(root.left, res);
}
res.add(root.val);
if (root.right != null) {
helper(root.right, res);
}
}
}
}

Complexity Analysis

Time complexity : O(n)O(n). The time complexity is O(n)O(n) because the recursive function is T(n) = 2 \cdot T(n/2)+1T(n)=2⋅T(n/2)+1.

Space complexity : The worst case space required is O(n)O(n), and in the average case it's O(log(n))O(log(n)) where nn is number of nodes.

Approach 2: Iterating method using Stack 迭代(基于栈)

The strategy is very similiar to the first method, the different is using stack.

伪代码如下(摘录自Wikipedia Tree_traversal)

iterativeInorder(node)
parentStack = empty stack
while (not parentStack.isEmpty() or node ≠ null)
if (node ≠ null)
parentStack.push(node)
node = node.left
else
node = parentStack.pop()
visit(node)
node = node.right

Python解法

class Solution(object):
def inorderTraversal(self, root): # 迭代
"""
:type root: TreeNode
:rtype: List[int]
"""
stack = []
res = []
while root or stack:
while root:
stack.append(root)
root = root.left
root = stack.pop()
res.append(root.val)
root = root.right
return res

Java解法

public class Solution {
public List < Integer > inorderTraversal(TreeNode root) {
List < Integer > res = new ArrayList < > ();
Stack < TreeNode > stack = new Stack < > ();
TreeNode curr = root;
while (curr != null || !stack.isEmpty()) {
while (curr != null) {
stack.push(curr);
curr = curr.left;
}
curr = stack.pop();
res.add(curr.val);
curr = curr.right;
}
return res;
}
}

Complexity Analysis

Time complexity : O(n)O(n).

Space complexity : O(n)O(n).

Approach 3: Morris Traversal

In this method, we have to use a new data structure-Threaded Binary Tree, and the strategy is as follows:

Step 1: Initialize current as root

Step 2: While current is not NULL,

If current does not have left child

    a. Add current’s value

    b. Go to the right, i.e., current = current.right

Else

    a. In current's left subtree, make current the right child of the rightmost node

    b. Go to this left child, i.e., current = current.left

For example:

          1
/ \
2 3
/ \ /
4 5 6

First, 1 is the root, so initialize 1 as current, 1 has left child which is 2, the current's left subtree is

         2
/ \
4 5

So in this subtree, the rightmost node is 5, then make the current(1) as the right child of 5. Set current = cuurent.left (current = 2). The tree now looks like:

         2
/ \
4 5
\
1
\
3
/
6

For current 2, which has left child 4, we can continue with thesame process as we did above

        4
\
2
\
5
\
1
\
3
/
6

then add 4 because it has no left child, then add 2, 5, 1, 3 one by one, for node 3 which has left child 6, do the same as above. Finally, the inorder taversal is [4,2,5,1,6,3].

For more details, please check Threaded binary tree and Explaination of Morris Method

Python解法

class Solution(object):
def inorderTraversal(self, root): # Morris Traversal
"""
:type root: TreeNode
:rtype: List[int]
"""
res = []
curr, pre = root, None
while curr:
if curr.left:
pre = curr.left
while pre.right:
pre = pre.right
pre.right = curr
curr.left, curr = None, curr.left
else:
res.append(curr.val)
curr = curr.right
return res

Java解法

class Solution {
public List < Integer > inorderTraversal(TreeNode root) {
List < Integer > res = new ArrayList < > ();
TreeNode curr = root;
TreeNode pre;
while (curr != null) {
if (curr.left == null) {
res.add(curr.val);
curr = curr.right; // move to next right node
} else { // has a left subtree
pre = curr.left;
while (pre.right != null) { // find rightmost
pre = pre.right;
}
pre.right = curr; // put cur after the pre node
TreeNode temp = curr; // store cur node
curr = curr.left; // move cur to the top of the new tree
temp.left = null; // original cur left be null, avoid infinite loops
}
}
return res;
}
}

Complexity Analysis

Time complexity : O(n)O(n). To prove that the time complexity is O(n)O(n), the biggest problem lies in finding the time complexity of finding the predecessor nodes of all the nodes in the binary tree. Intuitively, the complexity is O(nlogn)O(nlogn), because to find the predecessor node for a single node related to the height of the tree. But in fact, finding the predecessor nodes for all nodes only needs O(n)O(n) time. Because a binary Tree with nn nodes has n-1n−1 edges, the whole processing for each edges up to 2 times, one is to locate a node, and the other is to find the predecessor node. So the complexity is O(n)O(n).

Space complexity : O(n)O(n). Arraylist of size nn is used.

参考:

https://leetcode.com/problems/binary-tree-inorder-traversal/solution/

http://bookshadow.com/weblog/2015/01/19/leetcode-binary-tree-inorder-traversal/

[leetcode] 94. Binary Tree Inorder Traversal 二叉树的中序遍历的更多相关文章

  1. LeetCode 94. Binary Tree Inorder Traversal 二叉树的中序遍历 C++

    Given a binary tree, return the inorder traversal of its nodes' values. Example: Input: [,,] \ / Out ...

  2. [LeetCode] 94. Binary Tree Inorder Traversal(二叉树的中序遍历) ☆☆☆

    二叉树遍历(前序.中序.后序.层次.深度优先.广度优先遍历) 描述 解析 递归方案 很简单,先左孩子,输出根,再右孩子. 非递归方案 因为访问左孩子后要访问右孩子,所以需要栈这样的数据结构. 1.指针 ...

  3. 【LeetCode】Binary Tree Inorder Traversal(二叉树的中序遍历)

    这道题是LeetCode里的第94道题. 题目要求: 给定一个二叉树,返回它的中序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,3,2] 进阶: 递归算法很简单 ...

  4. [LeetCode] Binary Tree Inorder Traversal 二叉树的中序遍历

    Given a binary tree, return the inorder traversal of its nodes' values. For example:Given binary tre ...

  5. Leetcode94. Binary Tree Inorder Traversal二叉树的中序遍历(两种算法)

    给定一个二叉树,返回它的中序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,3,2] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 递归: class So ...

  6. [LeetCode] 144. Binary Tree Preorder Traversal 二叉树的先序遍历

    Given a binary tree, return the preorder traversal of its nodes' values. For example:Given binary tr ...

  7. Leetcode 94 Binary Tree Inorder Traversal 二叉树

    二叉树的中序遍历,即左子树,根, 右子树 /** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *lef ...

  8. [LeetCode] 145. Binary Tree Postorder Traversal 二叉树的后序遍历

    Given a binary tree, return the postorder traversal of its nodes' values. For example: Given binary ...

  9. [leetcode]94. Binary Tree Inorder Traversal二叉树中序遍历

    Given a binary tree, return the inorder traversal of its nodes' values. Example: Input: [1,null,2,3] ...

随机推荐

  1. Java东西太多,记录一些知识点

    实习两个月了,这两个月接触了不少东西,简单列举一下知识,未来需要多多学习和了解. 1.前端js.extjs4.Jquery(js框架这些基本现学现用): 2.基础不好要补补Servlet和JSP(再往 ...

  2. Android 上传大文件

    最近工作需要实现使用 Android 手机上传图片的功能, 参考了网络上的很多资料, 不过网络上的代码都仅仅适合上传较小的文件, 当上传较大文件时(我在自己的测试机器上发现是 2M 左右), 就会因为 ...

  3. C# 中的浅表副本与深表副本

    public class Student { public int age; public Student(int age) { this.age = age; } } public class Gr ...

  4. SqlServer和Oracle判断表和列是否存在

    SqlServer .判断表Users是否存在 if object_id(N'Users',N'U') is not null print '存在' else print '不存在' .判断表User ...

  5. 图片保存到数据库以及C#读取图片

    图片保存到数据库,如果是sqlserver就是Image类型,如果保存到Oracle就是blob类型,在c#中相对应的就是byte[]类型,同时只需要对读出的数据强制转换就行(byte[])objec ...

  6. Redis之有序集合命令

    Redis 有序集合(sorted set) Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员. 不同的是每个元素都会关联一个double类型的分数.redis正是通过 ...

  7. 手动添加 launcher 到 Ubuntu Unity

    本来,启动程序之后,在左边的launcher bar点右键,[Lock to Launcher]就可以的. 但是,有时候因为某种原因,需要手工添加. 这时候,就要参考下面的文章了 http://ask ...

  8. 雷林鹏分享:C# 多态性

    C# 多态性 多态性意味着有多重形式.在面向对象编程范式中,多态性往往表现为"一个接口,多个功能". 多态性可以是静态的或动态的.在静态多态性中,函数的响应是在编译时发生的.在动态 ...

  9. protected 与 internal

    protected:在当前类的“内部”  和  派生子类的“内部” 可访问(注意:实例对象不可访问 或者说 访问不到):如果静态,则在当前类内部和派生子类内部  具有“全局效果” internal:在 ...

  10. django-celery定时任务以及异步任务and服务器部署并且运行全部过程

    Celery 应用Celery之前,我想大家都已经了解了,什么是Celery,Celery可以做什么,等等一些关于Celery的问题,在这里我就不一一解释了. 应用之前,要确保环境中添加了Celery ...