力扣面試題04.06後繼者

設計一個算法,找出二叉搜索樹中指定節點的“下一個”節點(也即中序後繼)。
如果指定節點沒有對應的“下一個”節點,則返回null。
示例 1:
輸入: root = [2,1,3], p = 1
  2
 / \
1   3
輸出: 2
示例 2:
輸入: root = [5,3,6,2,4,null,null,1], p = 6

      5
     / \
    3   6
   / \
  2   4
 /   
1
輸出: null

吼吼,繼續更新,終於找到了答題人數比較少的啦,
我來理下思路,待會客官自己研究下代碼
首先說明整體思路是用的迭代
無非三種大情況:
1、其值比根節點值要大,那麼也就意味着這個節點在根節點的右子樹,我們由中序後繼得知,這樣的情況,返回值只會出現在右子樹裏面。這就可以把右子樹給單獨看做一個樹我們調用相同的算法去操作;
2、其值與根節點相同,那麼也就意味着其中序後繼爲根節點右子樹的最左邊
3、其值比根節點要小,那麼這個的情況就有些複雜了
3.1其值和根節點的左孩子相同,且左孩子無右孩子,直接返回根節點
3.2其值和根節點的左孩子相同且左孩子有右孩子,那麼我們需要找到左孩子的右孩子的最左節點
3.3若其值小於根節點左孩子,則繼續迭代
3.4若其值大於根節點左孩子,則迭代的返回值若爲空則則返回根節點,否則返回返回值。
第3種情況有點饒,大家自己畫畫樹的圖就好啦。

package medium;

public class succersor {
	 public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
		 TreeNode re=null;
		 if(root.val<p.val){//在右子樹
			 root=root.right;
			 if(root!=null){
				re= inorderSuccessor(root, p); 
			 }else
				 return null;
		 }
		 else if(root.val==p.val){
			 if(root.right!=null){
				 re=findleft(root.right);
			 }
			 return re;
		 }
		 else if(root.val>p.val){
			 if(root.left!=null&&root.left.right==null&&root.left.val==p.val){
				 return root;
			 }
			 else  if(root.left!=null&&root.left.right!=null&&root.left.val==p.val){
				 return findleft(root.left.right);
			 }
			 else if(root.left!=null&&root.left.val<p.val){
				 re =inorderSuccessor(root.left, p)==null? root:inorderSuccessor(root.left, p);
				 
			 }
			 else if(root.left!=null&&root.left.val>p.val){
			 re=inorderSuccessor(root.left, p);
			 }else
				 return null;
			 
		 }
		 return re;
		

	    }
	 private TreeNode findleft(TreeNode root) {
		while(root.left!=null){
			root=root.left;
		}
		return root;
	}
	public static void main(String[] args) {
		TreeNode root=new TreeNode(5);
		TreeNode r=new TreeNode(6);
	    TreeNode r2=new TreeNode(2);
		TreeNode r3=new TreeNode(4);
		root.left=new TreeNode(3);
		root.left.left=new TreeNode(1);
		root.left.right=r3;
		root.left.left.right=r2;
		root.right=r;
		succersor s=new succersor();
	System.out.println(s.inorderSuccessor(root, new TreeNode(4)).val);	
	} 

}

   public TreeNode inorderSuccessor2(TreeNode root, TreeNode p) {
	         // p存在右子樹,直接後繼就是右子樹的最左節點
	         if(p.right!=null){
	           p=p.right;
	           while(p.left!=null){
	             p=p.left;
	             }
	             return p;
	             }
	             //p不存在右子樹
	             TreeNode node=root;
	             TreeNode res=null;
	             while(p!=node){
	             if(p.val<node.val){
	              // node比p大,表示node在p的後繼路徑上
	                res=nodel;
	                node=node.left;
	                }else{
	                  // node比p小,表示node在p的前驅路徑上
	                node=node.right;
	                  }
	               }
	                return res;

OK,我從題解裏看到了另一個解法,他是用p節點是否有孩子進行判斷的。
但我認爲這種做法不夠好,若是p節點就是單個節點,你前面的判斷就呵呵啦

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章