zoukankan      html  css  js  c++  java
  • [LintCode] Inorder Successor in Binary Search Tree

    Given a binary search tree (See Definition) and a node in it, find the in-order successor of that node in the BST.

    If the given node has no in-order successor in the tree, return null.

    It's guaranteed p is one node in the given tree. (You can directly compare the memory address to find p)

    Example

    Given tree = [2,1] and node = 1:

      2
     /
    1
    

    return node 2.

    Given tree = [2,1,3] and node = 2:

      2
     / 
    1   3
    

    return node 3.

    Challenge 

    O(h), where h is the height of the BST.

    Solution 1. Recursive in-order traverse. O(n) runtime,  O(h) space

     1 public class Solution {
     2     private boolean foundP = false;
     3     private TreeNode successor = null;
     4     public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
     5         inOrderHelper(root, p);
     6         return successor;          
     7     }
     8     private void inOrderHelper(TreeNode node, TreeNode p) {
     9         if(node == null) {
    10             return;
    11         }
    12         inOrderHelper(node.left, p);
    13         //already found p's successor
    14         if(successor != null) {
    15             return;
    16         }
    17         //just found p
    18         else if(foundP) {
    19             successor = node;
    20             return;
    21         }
    22         if(node == p) {
    23             foundP = true;
    24         }
    25         inOrderHelper(node.right, p);
    26     }
    27 }

    Solution 2. Iterative in-order traverse. O(n) runtime, O(h) space

     1 public class Solution {
     2     public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
     3         Stack<TreeNode> stack = new Stack<TreeNode>();
     4         TreeNode curr = root;
     5         boolean findP = false;
     6         while(curr != null || stack.isEmpty() == false)
     7         {
     8             while(curr != null)
     9             {
    10                 stack.push(curr);
    11                 curr = curr.left;
    12             }
    13             curr = stack.pop();
    14             if(findP == true)
    15             {
    16                 return curr;
    17             }
    18             if(curr == p)
    19             {
    20                 findP = true;
    21             }
    22             curr = curr.right;
    23         }
    24         return null;
    25     }
    26 }

    Solution 3. O(h) runtime

    Since the given tree is a BST,  we can use the relation between p.val and root.val to cut the current search range into half.

    1. if root.val < p.val, then we need to look for p's successor in root's right subtree.

    2. if root.val > p.val, then root may be p's successor, or it is in root's left subtree.

    3. if root.val == p.val, if p has a right subtree, then p's successor is the smallest in p's right subtree.

    Based on the above analysis, we can solve this problem in O(h) runtime either recursively or iteratively.

    Iteration

    Use binary search to find the node p. p is guranteed to be a node in the given tree. 

    1. If the current node curr's value is smaller than p's value, we know p's successor has to be on the curr's 

    right subtree and curr can not be p's successor. So curr should be simply eliminated from being a possible 

    candidate. 

    2. If the current node curr's value is bigger than p's value, then we must keep curr as a potential successor 

    candidate because curr's value is bigger than p's value.

    3. After we've found p, we either check if p has a right subtree.

      a.If it does, then find the smallest node out of its right subtree and that will be the correct successor.

      b.If it does not have a right subtree, if successor is null, it means p is actually the last node, its successor 

       is nul; If successor is not null, since we only update successor when a node's value is bigger than p's value,

       and no right subtree of p means its successor is the node that is stored in the variable successor.

          So in both case a and b, nothing needs to be done, just return successor.

     1 public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
     2     if(root == null || p == null) {
     3         return null;
     4     }        
     5     TreeNode curr = root;
     6     TreeNode successor = null;
     7     while(curr != p) {
     8         if(curr.val < p.val) {
     9             curr = curr.right;
    10         }
    11         else {
    12             successor = curr;
    13             curr = curr.left;
    14         }
    15     }
    16     if(curr.right != null) {
    17         curr = curr.right;
    18         while(curr != null) {
    19             successor = curr;
    20             curr = curr.left;
    21         }            
    22     }
    23     return successor;
    24 }

    Recursion

    1.  If current node curr's value is <= p.value, it means we need to look for p's successor in curr's right subtree.

    2.  If curr's value is > p.value, it means p's successor will either be curr or a node from curr's left subtree. 

      a. if no successor is found from curr's left subtree, then there is only one possibility: curr is p's successor;

      b. if successor is found from curr's left subtree, then just return it.

     1 public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
     2     if(root == null) {
     3         return null;
     4     }
     5     if(root.val <= p.val) {
     6         return inorderSuccessor(root.right, p);
     7     }
     8     TreeNode left = inorderSuccessor(root.left, p);
     9     return (left != null) ? left : root;
    10 }

    Related Problems

    Validate Binary Search Tree

    Binary Search Tree Iterator

  • 相关阅读:
    VS2013使用scanf、gets及字符串函数编译报错error C4996: 'scanf': This function or variable may be unsafe. 原因及解决方案
    关于vs2013与office系列软件一起安装出现bug的情况描述以及解决办法——打开vs2013鼠标不动/动不了
    武汉华师驾校学车笔记_纪实
    vs2013由修改模式改为输入模式。
    解析:求最大公约数的“辗转相除法原理”
    关于scanf与scanf_s的区别,以及用scanf编译出错并且提示找不到可执行文件.exe的解决办法。
    [C编译器]在VS中编译调试C程序
    使用vs编译程序选择新建”空项目“与”win32控制台应用程序“的区别。
    AngularJS+Ionic开发-1.搭建开发环境
    PetaPoco源代码学习--3.Sql类
  • 原文地址:https://www.cnblogs.com/lz87/p/7478973.html
Copyright © 2011-2022 走看看