尋找二叉樹的最近公共祖先


尋找二叉樹的最近公共祖先

這道題在面試過程遇到了兩次了,感覺是一個高頻考點,特此總結一下

解題思路:

祖先定義: 若節點p 在節點root 的左子樹或者右子樹中,則稱root是p的祖先

最近公共祖先的定義: 設節點root 為節點p,q的最近公共祖先,若其左子節點root.left,和右子節點

root.right 都不是p,q的公共祖先在,則稱root 是最近的公共祖先

根據以上定義,若root是p,q的最近公共祖先,則只可能為以下情況之一:

1,p和q在root的子樹中,且分列root的兩側,即分別為左右子樹中。

2, p = root ,且q 在root 的左或右子樹中

3,q = root,且 p 在root 的左或者右子樹中

考慮通過遞歸對二叉樹進行后續遍歷,當遇到節點p 或者q 時返回,從底至頂回溯,當節點p ,q,在節點root兩側時,即為最近公共祖先,則向上返回root

遞歸解析

1,終止條件:

1,當越過葉子節點,則直接返回Null

2,當root 等於p ,q,則直接返回root

2.遞推工作

1,開啟遞歸左子節點,返回值記為left

2, 開啟遞歸右子節點,返回值記為right

3, 返回值

1,當left 和right 同時為空,說明,root 的左/右子樹中都不包含p,q. 返回Null

2, 當left 和right 同時不為空,說明,p,q,分別在root的兩側,因此root為最近的公共祖先,返回root

3, 當left 為空,right 不為空: p,q 都不在root 的左子樹中,直接返回right,具體可分為兩種情況:

  1. p,q, 其中一個在root 的右子樹中,p 或者q 就是root 的右子樹, 此時right 指向 p(假設為p )

  2. p,q,兩個基點都在root的右子樹中,此時的right 指向最近的公共祖先節點

4,當left 不為空,right 為空,直接返回left ,與3 同理


public static TreeNode lowestCommonAncestor (TreeNode root ,TreeNode p,TreeNoe q ){
   if(root==null || root == p || root == q ){
       return root;
  }
   TreeNode left =  lowestCommonAncestor(root.left,p,q );
   TreeNode right = lowestCommonAncestor(root.right,p,q );
   if(left === null &&right === null ){return null;}

   if(left == null ){return right; }
   if(right == null ){return left; }
   return root;
}

驗證:


import java.util.*;

public class TreeExercise1 {

   public static void main(String[] args ){
       TreeNode p3 =  new TreeNode(3);
       TreeNode p5 =  new TreeNode(5);
       TreeNode p1 =  new TreeNode(1);
       TreeNode p6 =  new TreeNode(6);
       TreeNode p2 =  new TreeNode(2);
       TreeNode p0 =  new TreeNode(0);
       TreeNode p8 =  new TreeNode(8);
       TreeNode p7 =  new TreeNode(7);
       TreeNode p4 =  new TreeNode(4);

       p3.left =  p5;
       p3.right = p1;
       p5.left =  p6;
       p5.right = p2;
       p1.left = p0;
       p1.right = p8;
       p2.left = p7;
       p2.right = p4;

//       inorferFix(p3);

       TreeNode res =  lowestCommonAncestor(p3,p2,p6);
       inorderFix(res);



  }
   public static TreeNode  lowestCommonAncestor(TreeNode root,TreeNode p,TreeNode q ){
       if(root==null || root==p || root== q ){
           return root;
      }
       TreeNode left =  lowestCommonAncestor(root.left,p,q);
       TreeNode right = lowestCommonAncestor(root.right,p,q);
       if(left==null && right == null ){ return null; }
       if(left == null ){return right; }
       if(right == null ){return left ; }
       return root;
  }
   
   private  static void  inorferFix(TreeNode  root ){
       if(root==null ){
           return;
      }
       if(root.left != null ){
           inorferFix(root.left);
      }
       System.out.println(root.val);
       if(root.right != null ){
           inorderFix(root.right);
      }
  }
}
https://www.nowcoder.com/ta/exam-qq




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM