劍指offer面試18 樹的子結構
一、題目
輸入兩棵二叉樹A,B,判斷B是不是A的子結構。(ps:我們約定空樹不是任意一個樹的子結構)
二、分析
要查詢樹A中是否存在和樹B結構一樣的子樹,我們可以分成兩步:
1. 在樹A中找到和樹B的根結點的值一樣的結點R;
2. 再判斷樹A中以R為根結點的子樹是否包含和樹B一樣的結構。
2.1 第一步
在樹A中查詢與樹B根結點的值一樣的結點,實際上就是樹的遍歷。我們採用遞迴來實現,遞迴的終止條件是樹A遍歷結點。
public boolean HasSubtree(TreeNode root1, TreeNode root2) {
boolean result = false;
if (root1 == null || root2 == null) {
return result;
}
if (root1.val == root2.val)
result = isTheSame(root1, root2);
if (!result)
result = HasSubtree(root1.left, root2);
if (!result)
result = HasSubtree(root1.right, root2);
return result;
/*
* 上面三個if可以用一行程式碼表示: return isTheSame(root1, root2) ||
* HasSubtree(root1.left, root2) || HasSubtree(root1.right, root2);
*/
}
2.2 第二步
判斷樹A中以R為根結點的子樹是不是和樹B具有相同的結構。同樣,我們也可以用遞迴的思路來考慮:如果結點R的值和樹B的根結點不相同,則以R為根結點的子樹和樹B肯定不具有相同的結點;如果它們的值相同,則遞迴地判斷它們各自的左右結點的值是否相同。遞迴的終止條件是到達了樹A或樹B的葉結點。
public boolean isTheSame(TreeNode root1, TreeNode root2) {
if (root2 == null) {//如果遞迴到達樹B的葉結點,則表示存在這樣的子樹
return true;
}
if (root1 == null) {//如果遞迴到達樹A的葉結點,則表示不存在這樣的子樹
return false;
}
if (root1.val != root2.val) {
return false;
}
return isTheSame(root1.left, root2.left) && isTheSame(root1.right, root2.right);
}
三、注意事項
- 一定要注意邊界條件的檢查,即檢查空指標。
- 設定遞迴呼叫的退出條件。
四、整體程式碼
/*
* 題目
* 輸入兩棵二叉樹A,B,判斷B是不是A的子結構。(ps:我們約定空樹不是任意一個樹的子結構)
*/
public class Test18 {
/*
* 先將二叉樹序列化,然後再比較子序列化字串是否存在於root1表示的序列化字串中 但是這種方法似乎不夠嚴謹,會出現錯誤
*/
public boolean HasSubtree2(TreeNode root1, TreeNode root2) {
String s1 = serialByPre(root1);
String s2 = serialByPre(root2);
return false;
}
// 用先序遍歷序列化二叉樹
public String serialByPre(TreeNode root) {
String result = null;
if (root == null) {
return "#!";
}
result = root.val + "!";
result += serialByPre(root.left);
result += serialByPre(root.right);
return result;
}
/*
* 1、先序遍歷二叉樹,比較遍歷節點也子二叉樹根節點;
* 2、如果相等,則分別比較二叉樹與子二叉樹的左右子結點是否相等,如果遇到不相等的子結點,則返回到第3步,如果都相等,則返回true
* 3、繼續遍歷二叉樹,直到遍歷完,如果還沒找到就返回。
*/
public boolean HasSubtree(TreeNode root1, TreeNode root2) {
boolean result = false;
if (root1 == null || root2 == null) {
return result;
}
if (root1.val == root2.val)
result = isTheSame(root1, root2);
if (!result)
result = HasSubtree(root1.left, root2);
if (!result)
result = HasSubtree(root1.right, root2);
return result;
/*
* 上面三個if可以用一行程式碼表示: return isTheSame(root1, root2) ||
* HasSubtree(root1.left, root2) || HasSubtree(root1.right, root2);
*/
}
public boolean isTheSame(TreeNode root1, TreeNode root2) {
if (root2 == null) {//如果遞迴到達樹B的葉結點,則表示存在這樣的子樹
return true;
}
if (root1 == null) {//如果遞迴到達樹A的葉結點,則表示不存在這樣的子樹
return false;
}
if (root1.val != root2.val) {
return false;
}
return isTheSame(root1.left, root2.left) && isTheSame(root1.right, root2.right);
}
/*
* 測試用例
* 樹A: 1
/ \
2 3
/ \
4 5
樹B: 1
/ \
2 3
*/
public static void main(String[] args) {
// 二叉樹
TreeNode root1 = new TreeNode(1);
TreeNode temp = root1;
TreeNode n1 = new TreeNode(2);
TreeNode n2 = new TreeNode(3);
temp.left = n1;
temp.right = n2;
temp = temp.left;
n1 = new TreeNode(4);
n2 = new TreeNode(5);
temp.left = n1;
temp.right = n2;
// 子二叉樹
TreeNode root2 = new TreeNode(2);
temp = root2;
n1 = new TreeNode(4);
n2 = new TreeNode(5);
Test18 t = new Test18();
System.out.println(t.HasSubtree(root1, root2));
}
}
相關文章
- 【劍指offer】樹的子結構
- 劍指offer-17:樹的子結構
- 劍指offer面試16 反轉連結串列面試
- 劍指offer——重建二叉樹二叉樹
- 【劍指offer】二叉樹深度二叉樹
- 《劍指offer》:[58]二叉樹的下一個結點二叉樹
- 劍指offer(四)重建二叉樹二叉樹
- 劍指offer面試17 合併兩個排序的連結串列面試排序
- 劍指Offer-40-二叉樹的深度二叉樹
- 劍指offer——二叉樹的映象C++二叉樹C++
- 【劍指offer】27. 二叉樹的映象二叉樹
- 劍指offer——二叉樹的深度C++二叉樹C++
- 《劍指offer》:[59]對稱的二叉樹二叉樹
- 《劍指offer》:[39]求解二叉樹的深度二叉樹
- 【劍指offer】連續子陣列的最大和陣列
- 劍指 Offer 07. 重建二叉樹二叉樹
- 【劍指offer】判斷二叉樹平衡二叉樹
- GitHub#algorithm#:《劍指offer》 的50道面試題GithubGo面試題
- 劍指offer | 55 - I. 二叉樹的深度二叉樹
- 「劍指offer」27道Mybatis面試題含解析MyBatis面試題
- 【劍指offer】字串的排列字串
- [劍指offer] 把二叉樹列印成多行二叉樹
- 《劍指offer》:[62]序列化二叉樹二叉樹
- 劍指offer面試題11 數值的整數次方面試題
- 【劍指offer】5.二叉樹的映象和列印二叉樹
- 力扣 - 劍指 Offer 27. 二叉樹的映象力扣二叉樹
- 劍指offer 面試題 7 :二叉樹的下一個節點是什麼?面試題二叉樹
- 劍指offer面試題15 連結串列中倒數第K個結點面試題
- 劍指 Offer 42.連續子陣列的最大和陣列
- 劍指Offer-連續子陣列中的最大和陣列
- 劍指offer面試題(41-50)——java實現面試題Java
- 劍指Offer——面試小提示(持續更新中)面試
- 《劍指offer》:[60]把二叉樹列印成多行二叉樹
- 【劍指offer】從上向下列印二叉樹二叉樹
- 《劍指offer》:[52]構建乘積陣列陣列
- 【劍指offer】【2】字串的空格字串
- 【劍指offer】字串的組合字串
- PHPer面試必看:分門別類帶你擼《劍指Offer》之二叉樹PHP面試二叉樹