劍指Offer26.樹的子結構
阿新 • • 發佈:2021-08-16
題目
輸入兩棵二叉樹A和B,判斷B是不是A的子結構。(約定空樹不是任意一個樹的子結構)
B是A的子結構, 即 A中有出現和B相同的結構和節點值。
例如:
給定的樹 A:
3
/ \
4 5
/ \
1 2
給定的樹 B:
4
/
1
返回 true,因為 B 與 A 的一個子樹擁有相同的結構和節點值。
示例 1:
輸入:A = [1,2,3], B = [3,1]
輸出:false
示例 2:
輸入:A = [3,4,5,1,2], B = [4,1]
輸出:true
限制:
0 <= 節點個數 <= 10000
來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/shu-de-zi-jie-gou-lcof
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。
解題思路
遞迴
首先先序遍歷A樹,找到B樹的根節點
找到B樹的根節點以後進一步校驗B是否和A的一個子樹擁有相同的結構和節點值
主函式:
如果兩棵樹都為空,返回true
如果其中一顆樹為空,返回false
如果當前A樹節點為B樹根節點,進入校驗函式
如果當前A樹節點不是B樹根# 題目
輸入兩棵二叉樹A和B,判斷B是不是A的子結構。(約定空樹不是任意一個樹的子結構)
B是A的子結構, 即 A中有出現和B相同的結構和節點值。
例如: 給定的樹 A: 3 / \ 4 5 / \ 1 2 給定的樹 B: 4 / 1 返回 true,因為 B 與 A 的一個子樹擁有相同的結構和節點值。 示例 1: 輸入:A = [1,2,3], B = [3,1] 輸出:false 示例 2: 輸入:A = [3,4,5,1,2], B = [4,1] 輸出:true 限制: 0 <= 節點個數 <= 10000
來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/shu-de-zi-jie-gou-lcof
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。
解題思路
遞迴
首先先序遍歷A樹,找到B樹的根節點 找到B樹的根節點以後進一步校驗B是否和A的一個子樹擁有相同的結構和節點值 主函式: 如果兩棵樹都為空,返回true 如果其中一顆樹為空,返回false 如果當前A樹節點為B樹根節點,進入校驗函式 如果當前A樹節點不是B樹根節點,遞迴進入A樹左子樹查詢 如果A樹左子樹也沒找到,遞迴進入A樹右子樹查詢 校驗函式: 如果B樹節點為空,表示B樹已經遍歷完,返回true 如果B樹不為空,A樹已經為空了,返回false 如果兩樹節點值不同,返回false 如果兩樹節點值相同,遞迴繼續效驗左右子樹 時間複雜度 O(MN): 其中 M,N 分別為樹 A 和 樹 B 的節點數量 空間複雜度 O(M) : 當樹 A 和樹 B 都退化為連結串列時,遞迴呼叫深度最大。節點,遞迴進入A樹左子樹查詢 如果A樹左子樹也沒找到,遞迴進入A樹右子樹查詢 校驗函式: 如果B樹節點為空,表示B樹已經遍歷完,返回true 如果B樹不為空,A樹已經為空了,返回false 如果兩樹節點值不同,返回false 如果兩樹節點值相同,遞迴繼續效驗左右子樹 時間複雜度 O(MN): 其中 M,N 分別為樹 A 和 樹 B 的節點數量 空間複雜度 O(M) : 當樹 A 和樹 B 都退化為連結串列時,遞迴呼叫深度最大。 /** * Definition for a binary tree node. * type TreeNode struct { * Val int * Left *TreeNode * Right *TreeNode * } */ func isSubStructure(A *TreeNode, B *TreeNode) bool { if A == nil && B == nil{ return true } // 空二叉樹不屬於任何樹子樹 if A == nil || B == nil{ return false } //var ret bool //if A.Val == B.Val{ // ret = helper(A,B) //} //if !ret{ // ret = isSubStructure(A.Left,B) //} //if !ret{ // ret = isSubStructure(A.Right,B) //} //return ret // 判斷兩二叉樹根節點是否相等,如果相等則繼續遞迴左右判斷是否包含整個子樹 // 如果不相等,遞迴左子樹 // 如果A左子樹也沒有包含B樹的,遞迴右子樹 return helper(A,B) || isSubStructure(A.Left,B) || isSubStructure(A.Right,B) } func helper(a *TreeNode,b *TreeNode) bool { // b樹為空,說明遍歷完了,A中包含子樹B if b == nil{ return true } // a樹為空,說明A樹遍歷完了,但B樹還有,所以A樹不包含子樹B if a == nil{ return false } // a樹和b樹節點不相等 if a.Val != b.Val{ return false } // 如果相等,繼續遞迴左右子樹判斷剩餘部分是否符合 return helper(a.Left,b.Left) && helper(a.Right,b.Right) }