LeetCode 285- Inorder Successor in Binary Search Tree


http://buttercola.blogspot.com/2015/10/leetcode-inorder-successor-in-bst.html
Given a binary search tree and a node in it, find the in-order successor of that node in the BST.
Note: If the given node has no in-order successor in the tree, return null.
Brute-force solution: O(n)
The most straight-forward solution is to do a in-order traversal of the BST. When we found the target node, we look for the smallest number greater than the node.
    public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
        if (root == null || p == null) {
            return null;
        }
         
        if (p.right != null) {
            return findMin(p.right);
        }
         
        // Case 2: p.right == null
        TreeNode succ = null;
        TreeNode q = root;
         
        while (q != null) {
            if (q.val > p.val) {
                succ = q;
                q = q.left;
            } else if (q.val < p.val) {
                q = q.right;
            } else {
                break;
            }
        }
         
        return succ;
    }
     
    private TreeNode findMin(TreeNode root) {
        TreeNode p = root;
         
        while (p.left != null) {
            p = p.left;
        }
         
        return p;
    }

X. https://blog.csdn.net/qq508618087/article/details/50886124
思路: 一种较为通用的方法是中序遍历一遍二叉树,记录结点的前一个结点,这样当前一个结点为p时,当前结点就是p的后继结点.这种方法适用于一般二叉树,时间复杂度为O(n).

但是这种方法并没有利用到二叉搜索树的性质. 因此我们还可以比较给定结点与根结点的大小, 如果根节点的值较大, 说明这个结点在根节点的左边, 因此此时根节点就是其不紧切后继, 然后再往左子树去比较. 如果根节点值较小, 说明我们要找的结点在根节点右边.这样一步步就可以找到最终的后继.
    TreeNode* inorderSuccessor(TreeNode* root, TreeNode* p) {
        if(!root) return root;
        inorderSuccessor(root->left, p);
        if(pre == p) ans = root;
        pre = root;
        inorderSuccessor(root->right, p);
        return ans;
    }
private:
    TreeNode *pre = NULL, *ans = NULL;
http://www.cnblogs.com/grandyang/p/5306162.html
这种方法充分地利用到了BST的性质,我们首先看根节点值和p节点值的大小,如果根节点值大,说明p节点肯定在左子树中,那么此时我们先将res赋为root,然后root移到其左子节点,循环的条件是root存在,我们再比较此时root值和p节点值的大小,如果还是root值大,我们重复上面的操作,如果p节点值,那么我们将root移到其右子节点,这样当root为空时,res指向的就是p的后继节点,参见代码如下:

cr    TreeNode* inorderSuccessor(TreeNode* root, TreeNode* p) {
        TreeNode *res = NULL;
        while (root) {
            if (root->val > p->val) {
                res = root;
                root = root->left;
            } else root = root->right;
        }
        return res;
    }

上面那种方法也可以写成递归形式,写法也比较简洁,但是需要把思路理清,当根节点值小于等于p节点值,说明p的后继节点一定在右子树中,所以对右子节点递归调用此函数,如果根节点值大于p节点值,那么有可能根节点就是p的后继节点,或者左子树中的某个节点是p的后继节点,所以先对左子节点递归调用此函数,如果返回空,说明根节点是后继节点,返回即可,如果不为空,则将那个节点返回,参见代码如下:

解法四:
    TreeNode* inorderSuccessor(TreeNode* root, TreeNode* p) {
        if (!root) return NULL;
        if (root->val <= p->val) {
            return inorderSuccessor(root->right, p);
        } else {
            TreeNode *left = inorderSuccessor(root->left, p);
            return left ? left : root;
        }
    }

    TreeNode* inorderSuccessor(TreeNode* root, TreeNode* p) {
        if(!root || !p) return NULL;
        TreeNode* ans = NULL;
        while(root)
        {
            if(root->val > p->val)
            {
                ans = root;
                root = root->left;
            }
            else root = root->right;
        }
        return ans;
    }
Inorder Successor in Binary Search Tree - GeeksforGeeks
Method 1 (Uses Parent Pointer)
In this method, we assume that every node has parent pointer.
The Algorithm is divided into two cases on the basis of right subtree of the input node being empty or not.
Input: node, root // node is the node whose Inorder successor is needed.
output: succ // succ is Inorder successor of node.
1) If right subtree of node is not NULL, then succ lies in right subtree. Do following.
Go to right subtree and return the node with minimum key value in right subtree.
2) If right sbtree of node is NULL, then succ is one of the ancestors. Do following.
Travel up using the parent pointer until you see a node which is left child of it's parent. The parent of such a node is the succ.
Also http://algorithms.tutorialhorizon.com/inorder-successor-in-binary-search-tree-using-parent-link/
struct node * inOrderSuccessor(struct node *root, struct node *n)
{
  // step 1 of the above algorithm
  if( n->right != NULL )
    return minValue(n->right);
  // step 2 of the above algorithm
  struct node *p = n->parent;
  while(p != NULL && n == p->right)
  {
     n = p;
     p = p->parent;
  }
  return p;
}
/* Given a non-empty binary search tree, return the minimum data 
    value found in that tree. Note that the entire tree does not need
    to be searched. */
struct node * minValue(struct node* node) {
  struct node* current = node;
  
  /* loop down to find the leftmost leaf */
  while (current->left != NULL) {
    current = current->left;
  }
  return current;
}

Method 2 - No parent node
1) If right subtree of node is not NULL, then succ lies in right subtree:
Go to right subtree and return the node with minimum key value in right subtree.
2) If right sbtree of node is NULL, then start from root and use search like below:
Travel down the tree, if a node’s data is greater than root’s data then go right side, otherwise go to left side.
Also check http://algorithms.tutorialhorizon.com/inorder-successor-in-binary-search-tree-without-using-parent-link/
http://www.cnblogs.com/jcliBlogger/p/4829200.html
http://blog.csdn.net/fightforyourdream/article/details/19860143
struct node * inOrderSuccessor(struct node *root, stuct node *n)
{
    // step 1 of the above algorithm
    if( n->right != NULL )
        return minValue(n->right);
    struct node *succ = NULL;
    // Start from root and search for successor down the tree
    while (root != NULL)
    {
        if (n->data < root->data)
        {
            succ = root;
            root = root->left;
        }
        else if (n->data > root->data)
            root = root->right;
        else
           break;
    }
    return succ;
}

Why?
LeetCode [285] Inorder Successor in BST
Note: If the given node has no in-order successor in the tree, return null.
The most straight-forward solution is to do a in-order traversal of the BST. When we found the target node, we look for the smallest number greater than the node.
    public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
        if (root == null || p == null) {
            return null;
        }
         
        if (p == root) {
            return p.right;
        }
         
        Stack<TreeNode> stack = new Stack<>();
        TreeNode q = root;
         
        while (!stack.isEmpty() || q != null) {
            if (q != null) {
                stack.push(q);
                q = q.left;
            } else {
                TreeNode curr = stack.pop();
                q = curr.right;
                 
                if (curr == p) {
                    if (curr.right != null) {
                        TreeNode m = curr.right;
                        while (m.left != null) {
                            m = m.left;
                        }
                        return m;
                         
                    } else if (!stack.isEmpty()){
                        return stack.pop();
                    }
                }
            }
        }
         
        return null;
    }
http://www.meetqun.com/thread-10973-1-1.html
  1.     public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
  2.         if (root == null || p == null) {
  3.             return null;9 E+ U$ W7 U/ @* ?$ o: X& v3 R7 U
  4.         }2 P" B( M) X, _' O; W  @
  5.         if (root.left == null && root.right == null) {
  6.             return null;! j1 P; x/ Q' U/ T
  7.         }4 C9 y' s. t+ }/ p4 v: O
  8.         
  9.         List<TreeNode> list = new LinkedList<TreeNode>();
  10.         helper(root, p.val, list);
  11.         
  12.         if (list.size() == 0) {) Q# o) z4 [; U% }8 ^$ g
  13.             return null;
  14.         }
  15.         return list.get(0);
  16.     }% l9 U7 H# v! W* q5 ^
  17.     ) ^) i% O* |# g' [) q
  18.     private void helper(TreeNode root, int targetValue, List<TreeNode> list) {
  19.         if (root == null) {
  20.             return;& G5 t- Q. V7 k) v
  21.         }7 J2 K2 F! m; X6 F
  22.         helper(root.left, targetValue, list);% y& @% ]7 r6 c- b
  23.         if (root.val > targetValue && list.size() == 0) {( p/ x1 G6 D2 [0 x
  24.             list.add(root);/ I, x2 P* ~* }( O
  25.         }
  26.         helper(root.right, targetValue, list);8 g: i4 X  c2 x7 b9 G+ m, b( h
  27.     }9

http://www.cnblogs.com/yrbbest/p/5037889.html
http://www.cnblogs.com/jcliBlogger/p/4829200.html
我们先建立一个空的successor,再取得一个root节点的reference。每次当node.val > p.val的时候,我们记录下当前的node节点,然后往左子树查找。否则向右子树查找。 向右子树查找的过程中不需要更新successor。
    public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
        if(root == null || p == null) {
            return null;
        }
        TreeNode successor = null;
        while(root != null) {
            if(p.val < root.val) {
                successor = root;
                root = root.left;
            } else {
                root = root.right;
            }
        }
        
        return successor;
    }
http://www.jiuzhang.com/solutions/inorder-successor-in-bst/
    public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
        TreeNode successor = null;
        while (root != null && root.val != p.val) {
            if (root.val > p.val) {
                successor = root;
                root = root.left;
            } else {
                root = root.right;
            }
        }
        
        if (root == null) {
            return null;
        }
        
        if (root.right == null) {
            return successor;
        }
        
        root = root.right;
        while (root.left != null) {
            root = root.left;
        }
        
        return root;
    }
http://buttercola.blogspot.com/2015/10/leetcode-inorder-successor-in-bst.html
If a node n doesn't have a right subtree, then we are done traversing n's subtree. We need to pick up where we left off with n's parent, which we'll call q.
If n was to the left of q, then the next node we should traverse should be q (again, since left - > current -> right).
If n were to the right of q, then we have fully traversed q's subtree as well. We need to traverse upwards from q until we find a node x that we have not fully traversed. How do we know that we have not fully traversed a node x? We know we have hit this case when we move from a left node to its parent. The left node is fully traversed, but its parent is not.
    public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
        if (root == null || p == null) {
            return null;
        }
         
        if (p.right != null) {
            return findMin(p.right);
        }
         
        // Case 2: p.right == null
        TreeNode succ = null;
        TreeNode q = root;
         
        while (q != null) {
            if (q.val > p.val) {
                succ = q;
                q = q.left;
            } else if (q.val < p.val) {
                q = q.right;
            } else {
                break;
            }
        }
         
        return succ;
    }
     
    private TreeNode findMin(TreeNode root) {
        TreeNode p = root;
         
        while (p.left != null) {
            p = p.left;
        }
         
        return p;
    }
http://leetcode.tgic.me/inorder-successor-in-bst/index.html
12     TreeNode leftMost(TreeNode root){
13         if(root == null) return null;
14         if(root.left != null) return leftMost(root.left);
15         return root;
16     }
17 
18     public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
19         if(root == p) {
20             return leftMost(p.right);
21         }
22 
23         if(p.val < root.val) {
24             p = inorderSuccessor(root.left, p);
25 
26             if(p == null){
27                 return root;
28             }
29 
30             return p;
31         }
32 
33         return inorderSuccessor(root.right, p);
34     }

TreeNode inorderSucc(TreeNode n) {
        if (n == null) return null;

        /* Found right children -> return leftmost node of right subtree. */
        if (n.right != null) {
                return leftMostChild(n.right);
        } else {
                TreeNode q = n;
                TreeNode x = q.parent;
                // Go up until we're on left instead of right
                while (x != null && x.left != q) {
                        q = x;
                        x = x.parent;
                }
                return x;
        }
}

TreeNode leftMostChild(TreeNode n) {
        if (n == null) {
                return null;
        }
        while (n.left != null) {
                n = n.left;
        }
        return n;
}
Read full article from Inorder Successor in Binary Search Tree - GeeksforGeeks

Labels

LeetCode (1432) GeeksforGeeks (1122) LeetCode - Review (1067) Review (882) Algorithm (668) to-do (609) Classic Algorithm (270) Google Interview (237) Classic Interview (222) Dynamic Programming (220) DP (186) Bit Algorithms (145) POJ (141) Math (137) Tree (132) LeetCode - Phone (129) EPI (122) Cracking Coding Interview (119) DFS (115) Difficult Algorithm (115) Lintcode (115) Different Solutions (110) Smart Algorithm (104) Binary Search (96) BFS (91) HackerRank (90) Binary Tree (86) Hard (79) Two Pointers (78) Stack (76) Company-Facebook (75) BST (72) Graph Algorithm (72) Time Complexity (69) Greedy Algorithm (68) Interval (63) Company - Google (62) Geometry Algorithm (61) Interview Corner (61) LeetCode - Extended (61) Union-Find (60) Trie (58) Advanced Data Structure (56) List (56) Priority Queue (53) Codility (52) ComProGuide (50) LeetCode Hard (50) Matrix (50) Bisection (48) Segment Tree (48) Sliding Window (48) USACO (46) Space Optimization (45) Company-Airbnb (41) Greedy (41) Mathematical Algorithm (41) Tree - Post-Order (41) ACM-ICPC (40) Algorithm Interview (40) Data Structure Design (40) Graph (40) Backtracking (39) Data Structure (39) Jobdu (39) Random (39) Codeforces (38) Knapsack (38) LeetCode - DP (38) Recursive Algorithm (38) String Algorithm (38) TopCoder (38) Sort (37) Introduction to Algorithms (36) Pre-Sort (36) Beauty of Programming (35) Must Known (34) Binary Search Tree (33) Follow Up (33) prismoskills (33) Palindrome (32) Permutation (31) Array (30) Google Code Jam (30) HDU (30) Array O(N) (29) Logic Thinking (29) Monotonic Stack (29) Puzzles (29) Code - Detail (27) Company-Zenefits (27) Microsoft 100 - July (27) Queue (27) Binary Indexed Trees (26) TreeMap (26) to-do-must (26) 1point3acres (25) GeeksQuiz (25) Merge Sort (25) Reverse Thinking (25) hihocoder (25) Company - LinkedIn (24) Hash (24) High Frequency (24) Summary (24) Divide and Conquer (23) Proof (23) Game Theory (22) Topological Sort (22) Lintcode - Review (21) Tree - Modification (21) Algorithm Game (20) CareerCup (20) Company - Twitter (20) DFS + Review (20) DP - Relation (20) Brain Teaser (19) DP - Tree (19) Left and Right Array (19) O(N) (19) Sweep Line (19) UVA (19) DP - Bit Masking (18) LeetCode - Thinking (18) KMP (17) LeetCode - TODO (17) Probabilities (17) Simulation (17) String Search (17) Codercareer (16) Company-Uber (16) Iterator (16) Number (16) O(1) Space (16) Shortest Path (16) itint5 (16) DFS+Cache (15) Dijkstra (15) Euclidean GCD (15) Heap (15) LeetCode - Hard (15) Majority (15) Number Theory (15) Rolling Hash (15) Tree Traversal (15) Brute Force (14) Bucket Sort (14) DP - Knapsack (14) DP - Probability (14) Difficult (14) Fast Power Algorithm (14) Pattern (14) Prefix Sum (14) TreeSet (14) Algorithm Videos (13) Amazon Interview (13) Basic Algorithm (13) Codechef (13) Combination (13) Computational Geometry (13) DP - Digit (13) LCA (13) LeetCode - DFS (13) Linked List (13) Long Increasing Sequence(LIS) (13) Math-Divisible (13) Reservoir Sampling (13) mitbbs (13) Algorithm - How To (12) Company - Microsoft (12) DP - Interval (12) DP - Multiple Relation (12) DP - Relation Optimization (12) LeetCode - Classic (12) Level Order Traversal (12) Prime (12) Pruning (12) Reconstruct Tree (12) Thinking (12) X Sum (12) AOJ (11) Bit Mask (11) Company-Snapchat (11) DP - Space Optimization (11) Dequeue (11) Graph DFS (11) MinMax (11) Miscs (11) Princeton (11) Quick Sort (11) Stack - Tree (11) 尺取法 (11) 挑战程序设计竞赛 (11) Coin Change (10) DFS+Backtracking (10) Facebook Hacker Cup (10) Fast Slow Pointers (10) HackerRank Easy (10) Interval Tree (10) Limited Range (10) Matrix - Traverse (10) Monotone Queue (10) SPOJ (10) Starting Point (10) States (10) Stock (10) Theory (10) Tutorialhorizon (10) Kadane - Extended (9) Mathblog (9) Max-Min Flow (9) Maze (9) Median (9) O(32N) (9) Quick Select (9) Stack Overflow (9) System Design (9) Tree - Conversion (9) Use XOR (9) Book Notes (8) Company-Amazon (8) DFS+BFS (8) DP - States (8) Expression (8) Longest Common Subsequence(LCS) (8) One Pass (8) Quadtrees (8) Traversal Once (8) Trie - Suffix (8) 穷竭搜索 (8) Algorithm Problem List (7) All Sub (7) Catalan Number (7) Cycle (7) DP - Cases (7) Facebook Interview (7) Fibonacci Numbers (7) Flood fill (7) Game Nim (7) Graph BFS (7) HackerRank Difficult (7) Hackerearth (7) Inversion (7) Kadane’s Algorithm (7) Manacher (7) Morris Traversal (7) Multiple Data Structures (7) Normalized Key (7) O(XN) (7) Radix Sort (7) Recursion (7) Sampling (7) Suffix Array (7) Tech-Queries (7) Tree - Serialization (7) Tree DP (7) Trie - Bit (7) 蓝桥杯 (7) Algorithm - Brain Teaser (6) BFS - Priority Queue (6) BFS - Unusual (6) Classic Data Structure Impl (6) DP - 2D (6) DP - Monotone Queue (6) DP - Unusual (6) DP-Space Optimization (6) Dutch Flag (6) How To (6) Interviewstreet (6) Knapsack - MultiplePack (6) Local MinMax (6) MST (6) Minimum Spanning Tree (6) Number - Reach (6) Parentheses (6) Pre-Sum (6) Probability (6) Programming Pearls (6) Rabin-Karp (6) Reverse (6) Scan from right (6) Schedule (6) Stream (6) Subset Sum (6) TSP (6) Xpost (6) n00tc0d3r (6) reddit (6) AI (5) Abbreviation (5) Anagram (5) Art Of Programming-July (5) Assumption (5) Bellman Ford (5) Big Data (5) Code - Solid (5) Code Kata (5) Codility-lessons (5) Coding (5) Company - WMware (5) Convex Hull (5) Crazyforcode (5) DFS - Multiple (5) DFS+DP (5) DP - Multi-Dimension (5) DP-Multiple Relation (5) Eulerian Cycle (5) Graph - Unusual (5) Graph Cycle (5) Hash Strategy (5) Immutability (5) Java (5) LogN (5) Manhattan Distance (5) Matrix Chain Multiplication (5) N Queens (5) Pre-Sort: Index (5) Quick Partition (5) Quora (5) Randomized Algorithms (5) Resources (5) Robot (5) SPFA(Shortest Path Faster Algorithm) (5) Shuffle (5) Sieve of Eratosthenes (5) Strongly Connected Components (5) Subarray Sum (5) Sudoku (5) Suffix Tree (5) Swap (5) Threaded (5) Tree - Creation (5) Warshall Floyd (5) Word Search (5) jiuzhang (5)

Popular Posts