LeetCode Binary Tree Inorder Traversal

54 篇文章 0 订阅
32 篇文章 0 订阅

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

本题与Binary Tree Preorder Traversal相呼应。可以分别采用Recursion, Iteration 和 Morris Traversal 三种方法。

Method 1: Recursion

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

Time O(n), Space O(logn).

AC Java:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> ls = new ArrayList<Integer>();
        inorderTraversal(root, ls);
        return ls;
    }
   public void inorderTraversal(TreeNode root, List<Integer> ls){
       if(root == null){
           return;
       }
       inorderTraversal(root.left, ls);
       ls.add(root.val);
       inorderTraversal(root.right, ls);
   }
 }

Method 2: Iteration + Stack

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

Time O(n), Space O(logn).

AC Java:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
   //Method 2: Iteration
   public List<Integer> inorderTraversal(TreeNode root) {
       List<Integer> ls = new ArrayList<Integer>();
       Stack<TreeNode> stk = new Stack<TreeNode>();
       while(root!=null || !stk.empty()){
           if(root!=null){
               stk.push(root);
               root = root.left;
           }else{
               root = stk.pop();
               ls.add(root.val);
               root = root.right;
           }
       }
       return ls;
   }
 }

Method 3:

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

Time 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:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
   //Method 3: Morris Traversal
   public List<Integer> inorderTraversal(TreeNode root) {
       List<Integer> ls = new ArrayList<Integer>();
       TreeNode cur = root;
       TreeNode pre = null;
       while(cur != null){
           if(cur.left == null){
               ls.add(cur.val);
               cur = cur.right;
           }
           else{
               //Left node is not null, find predcessor 
               pre = cur.left;
               while(pre.right!=null && pre.right!=cur){ //error
                   pre = pre.right;
               }
               if(pre.right == null){
                   pre.right = cur;
                   cur = cur.left;
               }else{
                   ls.add(cur.val);
                   pre.right = null;
                   cur = cur.right;
               }
           }
       }
       return ls;
   }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值