トピックの説明
2つの二分木AとBを入力し、BがAの部分構造であるかどうかを判定します。(空のツリーはどのツリーの部分構造でもないことを約束します)
B は A の部分構造です。つまり、A は B と同じ構造とノード値を持ちます。
例:
与えられた木 A:
3 / \ 4 5 / \ 1 2
木 B が与えられると、次のようになります。
4 / 1
B は A のサブツリーと同じ構造とノード値を持つため、true を返します。
一連の考え
このタイプの問題は文字列マッチングに似ており、解決プロセスは大きく 2 つのステップに分かれています。
- ルートノードと一致します。AB と一致するノード C を見つけます。
- 他のノードと一致します。C のサブツリーが B のサブツリーと一致することを確認します。
マッチングに参加するバイナリ ツリーは、それ自体と一致する 1 つ、または相互に一致する 2 つです。
次の 2 つのことを行います。
- ツリー A の各ノードを事前順序で走査します。
- ツリー A のすべてのノードをルートとするサブツリーにツリー B が含まれているかどうかを確認します。
ビッグガイコード:
class Solution {
public boolean isSubStructure(TreeNode A, TreeNode B) {
return (A != null && B != null) && (recur(A, B) || isSubStructure(A.left, B) || isSubStructure(A.right, B));
}
boolean recur(TreeNode A, TreeNode B) {
if(B == null) return true;
if(A == null || A.val != B.val) return false;
return recur(A.left, B.left) && recur(A.right, B.right);
}
}
民法典:
class Solution {
public boolean isSubStructure(TreeNode A, TreeNode B) {
if (B == null || A == null) {
return false;
}
if (A.val == B.val && (helper(A.left, B.left) && helper(A.right, B.right))) {
return true;
}
return isSubStructure(A.left, B) || isSubStructure(A.right, B);
}
private boolean helper(TreeNode root1, TreeNode root2) {
if (root2 == null) {
return true;
}
if (root1 == null) {
return false;
}
if (root1.val == root2.val) {
return helper(root1.left, root2.left) && helper(root1.right, root2.right);
} else {
return false;
}
}
}