Given a binary search tree and a node in it, find the in-order successor of that node in the BST.node
Note: If the given node has no in-order successor in the tree, return null.code
時間 O(N) 空間 O(N)it
題目給定根節點和目標節點。目標節點若是有右節點的狀況比較好處理,咱們只要返回它的右節點的最左邊的節點就好了(右節點本身沒有左節點時則是右節點自己)。若是目標節點沒有右節點,說明比目標節點稍大的節點應該在上面,由於咱們知道目標節點的左節點確定是比目標節點要小的。io
那怎麼知道目標節點的上面是什麼呢?這時就須要從根節點搜索到目標節點了。這裏要注意的是,目標節點的父親不必定比目標節點大,由於有可能目標節點的是其父親的右孩子。因此咱們要找的上面,其實是從目標節點向根節點回溯時,第一個比目標節點大的節點。最差的狀況下,若是回溯到根節點仍是比目標節點要小的話,說明目標節點就是整個數最大的數了,這時候返回空。class
那怎麼實現目標節點向根節點回溯,這裏用一個棧就好了,在咱們尋找目標節點時,把路徑上的節點都壓入棧中。搜索
public class Solution { public TreeNode inorderSuccessor(TreeNode root, TreeNode p) { Stack<TreeNode> stk = new Stack<TreeNode>(); TreeNode curr = root; // 找到目標節點並把路徑上的節點壓入棧 while(curr != p){ stk.push(curr); if(curr.val > p.val){ curr = curr.left; } else { curr = curr.right; } } // 若是目標節點有右節點,則找到其右節點的最左邊的節點,就是下一個數 if(curr.right != null){ curr = curr.right; while(curr.left != null){ curr = curr.left; } return curr; } else { // 若是沒有右節點,pop棧找到第一個比目標節點大的節點 while(!stk.isEmpty() && stk.peek().val < curr.val){ stk.pop(); } // 若是棧都pop空了尚未比目標節點大的,說明沒有更大的了 return stk.isEmpty() ? null : stk.pop(); } } }