劍指offer——樹的子結構 (JAVA代碼)


版權聲明:本文為博主原創文章,未經博主允許不得轉載。

題目描述

  輸入兩棵二叉樹A,B,判斷B是不是A的子結構。(ps:我們約定空樹不是任意一個樹的子結構)。

解題思路:

  首先看牛客網給出的測試用例:

  

   一般對於樹的操作不像鏈表一樣,操作更復雜,如果使用循環遍歷的話,對於非完全二叉樹規律難尋,一般通用的方法就是使用遞歸求解,本題也不例外,同樣使用遞歸求解,求解的大體思路是首先判斷B的根節點和A的根節點是否相同(這里的相同是指節點的值相同並且左右子節點相同),如果相同比較他們的左右子節點,這一步驟是相同的,可以用遞歸完成,直到B遍歷到每個尾節點,如果這一過程比較的所有節點是相同的,則證明B是A的子結構。如果B的根節點和A的根節點不同,則A向他的左右子節點滑動,然后繼續跟B的子節點比較,步驟同上。

  遞歸的使用可以用我總結的三步來完成。求解過程如下:

  1. 遞歸截止條件。
  遞歸的截止條件是為了遞歸能夠避免無限循環下去,首先來分析什么情況下遞歸截止返回遍歷結果,(1)根據題目要求,如果B數是個空樹,遞歸截止。(2)如果被遍歷的樹A是空樹,自然而然遞歸截止。(3)如果比較的是B的尾節點,無法進行下去,遞歸也會截止。(4)如果A樹從頭遍歷到尾始終沒有和B的節點相同的節點,遞歸截止。
  2. 遞歸的前后銜接。
  如果A的根節點值以及左右子節點情況和B的根節點完全相同,那么A和B都繼續滑動到他們的左右子節點進行比較;如果A的根節點值和B的根節點值是相同的,但是左右子節點的情況是不相同的,那么只滑動A到他的左右子節點再與B比較。如果A的根節點的值和B的根節點的值不相同,那么A直接滑動到他的左右自己點再和B的根節點比較,直到遍歷完成。
  3. 遞歸節點數據的處理。
  根據題目,本題目中用到的遞歸並沒有數據處理,只是比較判斷兩個樹節點是否相同。對於其他遞歸,可以具體情況具體對待。

 

源碼:

 1     /**
 2      * 輸入兩棵二叉樹A,B,判斷B是不是A的子結構。
 3      * @param root1 A樹
 4      * @param root2 B數
 5      * @return 
 6      */
 7     public static boolean HasSubtree(TreeNode root1,TreeNode root2) {
 8         
 9         if (root2==null) {        //空樹不是任意一個樹的子結構
10             return false;
11         }
12         if (root1==null) {        //如果A為空,那肯定返回false
13             return false;
14         }
15         if(root2.val==root1.val){        //A和B比較的根節點的值相同
16             
17             if (root2.left==null&&root2.right==null) {        //比較的節點是B的尾節點,遞歸截止
18                 return true;
19             }
20             //下面三種比較的是比較的節點完全相同的情況
21             if ((root2.left!=null&&root2.right!=null)&&(root1.left!=null&&root1.right!=null)&&root2.left.val==root1.left.val&&root2.right.val==root1.right.val) {
22                 return HasSubtree(root1.left,root2.left)&& HasSubtree(root1.right,root2.right);
23             }else if ((root2.left!=null&&root2.right==null)&&(root1.left!=null&&root1.right==null)&&root2.left.val==root1.left.val) {
24                 return HasSubtree(root1.left,root2.left);
25             }else if ((root2.left==null&&root2.right!=null)&&(root1.left==null&&root1.right!=null)&&root2.right.val==root1.right.val) {
26                 return HasSubtree(root1.right,root2.right);
27             }else{        //比較的節點不同,A向左右子節點移動一個再比較
28                 if (root1.left!=null&&root1.right!=null) {
29                     return  HasSubtree(root1.left,root2)|| HasSubtree(root1.right,root2);
30                 }else if(root1.left==null&&root1.right!=null){
31                     return  HasSubtree(root1.right,root2);
32                 }else if(root1.left!=null&&root1.right==null){
33                     return  HasSubtree(root1.left,root2);
34                 }else {
35                     return false;
36                 }    
37             }
38         //比較的根節點的值不相同,直接向左右子節點滑動    
39         }else if(root1.left!=null&&root1.right==null){
40             return HasSubtree(root1.left,root2);
41         }else if(root1.left==null&&root1.right!=null){
42             return HasSubtree(root1.right,root2);
43         }else{
44             return false;
45         }
46     }

 


免責聲明!

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



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