自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

聊聊判斷二叉樹A中是否包含子樹B

開發(fā) 前端
輸入兩棵二叉樹A和B,判斷B是不是A的子結(jié)構(gòu)。(約定空樹不是任意一個(gè)樹的子結(jié)構(gòu))B是A的子結(jié)構(gòu), 即 A中有出現(xiàn)和B相同的結(jié)構(gòu)和節(jié)點(diǎn)值。

[[437107]]

Leetcode : https://leetcode-cn.com/problems/shu-de-zi-jie-gou-lcof

“GitHub : https://github.com/nateshao/leetcode/blob/main/algo-notes/src/main/java/com/nateshao/sword_offer/topic_20_isSubStructure/Solution.java

判斷二叉樹A中是否包含子樹B

“題目描述 :輸入兩棵二叉樹A和B,判斷B是不是A的子結(jié)構(gòu)。(約定空樹不是任意一個(gè)樹的子結(jié)構(gòu))B是A的子結(jié)構(gòu), 即 A中有出現(xiàn)和B相同的結(jié)構(gòu)和節(jié)點(diǎn)值。例如:給定的樹 A:

  1.        3 
  2.       / \ 
  3.     4   5 
  4.   / \ 
  5. 1   2 

給定的樹 B:

  1.  
  2.  

返回 true,因?yàn)?B 與 A 的一個(gè)子樹擁有相同的結(jié)構(gòu)和節(jié)點(diǎn)值。示例 1:

  1. 輸入:A = [1,2,3], B = [3,1] 
  2.  
  3. 輸出:false 

示例 2:

  1. 輸入:A = [3,4,5,1,2], B = [4,1] 
  2.  
  3. 輸出:true 

限制:0 <= 節(jié)點(diǎn)個(gè)數(shù) <= 10000

解題思路:若樹B是樹A的子結(jié)構(gòu),則子結(jié)構(gòu)的根節(jié)點(diǎn)可能為樹A的任意一個(gè)節(jié)點(diǎn)。因此,判斷樹B是否是樹A的子結(jié)構(gòu),需完成以下兩步工作:

先序遍歷樹A中的每個(gè)節(jié)點(diǎn)nA ; (對(duì)應(yīng)函數(shù) isSubStructure(A, B) )

判斷樹A中以nA為根節(jié)點(diǎn)的子樹否包含樹B。(對(duì)應(yīng)函數(shù)recur(A,B))

算法流程:

“名詞規(guī)定:樹 A 的根節(jié)點(diǎn)記作 節(jié)點(diǎn) A ,樹 B 的根節(jié)點(diǎn)稱為 節(jié)點(diǎn) B 。

recur(A, B) 函數(shù):

1.終止條件:

  • 當(dāng)節(jié)點(diǎn) B為空:說明樹 B 已匹配完成(越過葉子節(jié)點(diǎn)),因此返回 true ;
  • 當(dāng)節(jié)點(diǎn) A為空:說明已經(jīng)越過樹 A 葉子節(jié)點(diǎn),即匹配失敗,返回 false ;
  • 當(dāng)節(jié)點(diǎn) A 和 B 的值不同:說明匹配失敗,返回 false ;

2.返回值:

  • 判斷A和B的左子節(jié)點(diǎn)是否相等,即recur(A. left, B. left) ;
  • 判斷A和B的右子節(jié)點(diǎn)是否相等,即recur(A. right,B. right) ;

isSubStructure(A, B)函數(shù):

  • 特例處理 :當(dāng)樹A為空或樹B為空時(shí),直接返回false;
  • 返回值 :若樹B是樹A的子結(jié)構(gòu),則必滿足以下三種情況之一,因此用或|連接;
    • 以節(jié)點(diǎn)A為根節(jié)點(diǎn)的子樹包含樹B,對(duì)應(yīng)recur(A,B);
    • 樹B是樹A左子樹的子結(jié)構(gòu),對(duì)應(yīng)isSubStructure(A. left, B) ;
    • 樹B是樹A右子樹的子結(jié)構(gòu),對(duì)應(yīng)isSubStructure(A. right, B) ;

以讓 2. 3.實(shí)質(zhì)上是在對(duì)樹A做先序遍歷。

復(fù)雜度分析:

  • 時(shí)間復(fù)雜度O(MN): 中M,N分別為樹A和樹B的節(jié)點(diǎn)數(shù)量;先序遍歷樹A占用0(M),每次調(diào)用recur(A, B)判斷占用O(N)。
  • 空間復(fù)雜度O(M):
    • 當(dāng)樹A和樹B都退化為鏈表時(shí),遞歸調(diào)用深度最大。
    • 當(dāng)M≤N時(shí),遍歷樹A與遞歸判斷的總遞歸深度為M ;
    • 當(dāng)M> N時(shí),最差情況為遍歷至樹A葉子節(jié)點(diǎn),此時(shí)總遞歸深度為M。
  1. package com.nateshao.sword_offer.topic_20_isSubStructure; 
  2.  
  3. /** 
  4.  * @date Created by 邵桐杰 on 2021/11/23 19:19 
  5.  * @微信公眾號(hào) 程序員千羽 
  6.  * @個(gè)人網(wǎng)站 www.nateshao.cn 
  7.  * @博客 https://nateshao.gitee.io 
  8.  * @GitHub https://github.com/nateshao 
  9.  * @Gitee https://gitee.com/nateshao 
  10.  * Description: 判斷二叉樹A中是否包含子樹B 
  11.  */ 
  12. class Solution { 
  13.  
  14.     /** 
  15.      * 精選解答 
  16.      * @param A 
  17.      * @param B 
  18.      * @return 
  19.      */ 
  20.     public static boolean isSubStructure1(TreeNode A, TreeNode B) { 
  21.         return (A != null && B != null) && (recur1(A, B) || isSubStructure1(A.left, B) || isSubStructure1(A.right, B)); 
  22.     } 
  23.  
  24.     public static boolean recur1(TreeNode A, TreeNode B) { 
  25.         if (B == nullreturn true
  26.         if (A == null || A.val != B.val) return false
  27.         return recur1(A.left, B.left) && recur1(A.right, B.right); 
  28.     } 
  29.      
  30.     /*********************************** 法二 *********************************************/ 
  31.     //遍歷A的每一個(gè)節(jié)點(diǎn) 
  32.     public boolean isSubStructure(TreeNode A, TreeNode B) { 
  33.         if (A == null || B == nullreturn false;//約定空樹不是任意一個(gè)樹的子結(jié)構(gòu) 
  34.         return recur(A, B) || isSubStructure(A.left, B) || isSubStructure(A.right, B); 
  35.     } 
  36.  
  37.     //同時(shí)遍歷A和B的相同位置節(jié)點(diǎn) 
  38.     boolean recur(TreeNode A, TreeNode B) { 
  39.         //當(dāng)B某個(gè)節(jié)點(diǎn)為null,則無需比較了,直接返回true,比較其他節(jié)點(diǎn) 
  40.         if (B == nullreturn true
  41.         //如果相同位置的兩個(gè)節(jié)點(diǎn)不相同,則返回false,不用再繼續(xù)比較了 
  42.         if (A == null || A.val != B.val) return false
  43.         //繼續(xù)往下遍歷比較 
  44.         return recur(A.left, B.left) && recur(A.right, B.right); 
  45.     } 
  46.  
  47.     public class TreeNode { 
  48.         int val; 
  49.         TreeNode left
  50.         TreeNode right
  51.  
  52.         TreeNode(int x) { 
  53.             val = x; 
  54.         } 
  55.     } 

 

參考鏈接:https://leetcode-cn.com/problems/shu-de-zi-jie-gou-lcof/solution/mian-shi-ti-26-shu-de-zi-jie-gou-xian-xu-bian-li-p

 

責(zé)任編輯:武曉燕 來源: 程序員千羽
相關(guān)推薦

2021-10-12 09:25:11

二叉樹樹形結(jié)構(gòu)

2020-04-27 07:05:58

二叉樹左子樹右子樹

2021-12-03 09:16:03

二叉樹打印平衡

2021-04-19 07:47:42

數(shù)據(jù)結(jié)構(gòu)二叉樹Tree

2021-04-20 08:37:14

數(shù)據(jù)結(jié)構(gòu)二叉樹

2021-03-17 08:19:22

二叉樹LeetCode

2013-07-15 16:35:55

二叉樹迭代器

2021-09-02 11:31:28

二叉搜索樹迭代法公共祖先

2023-02-01 07:27:46

序列化二叉樹根節(jié)點(diǎn)

2021-09-29 10:19:00

算法平衡二叉樹

2020-09-23 18:25:40

算法二叉樹多叉樹

2021-04-28 20:12:27

數(shù)據(jù)結(jié)構(gòu)創(chuàng)建

2020-11-25 08:25:02

二叉樹節(jié)點(diǎn)

2020-12-22 08:56:51

JavaScript數(shù)據(jù)結(jié)構(gòu)前端

2022-10-26 23:58:02

二叉樹數(shù)組算法

2021-05-06 17:46:30

二叉樹數(shù)據(jù)結(jié)構(gòu)

2021-08-26 11:31:11

二叉樹數(shù)據(jù)結(jié)構(gòu)算法

2021-03-22 08:23:29

LeetCode二叉樹節(jié)點(diǎn)

2021-08-27 11:36:44

二叉樹回溯節(jié)點(diǎn)

2023-05-08 15:57:16

二叉樹數(shù)據(jù)結(jié)構(gòu)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)