🐈
LeetCode 331. Verify Preorder Serialization of a Binary Tree
問題
ある入力に対してBTをpreorderで走査した結果としてありうる場合はtrue,そうでない場合はfalseを返してください。
ここで#はノードがない(null)ことを意味します。
入力例:"9,3,4,#,#,1,#,#,2,#,6,#,#"
解答
BTを成り立たせる条件を整理する。nullもノードに含めるとして
- 全てのnullでないノードは2つの子ノード(outdegree)と1つの親ノード(indegree)を持つ
- 全てのnullノードは子ノード(outdegree)が存在せず1つの親ノード(indegree)を持つ
ここで入力の各値に対して
diff = outdegree - indegree
を考える。次の値は正しいノードであれば(rootでない限り)必ず親を1つ持つのでdiff -= 1
する。さらにこのノードがnullでない場合は子ノードが2つあるはずなので(nullも子ノードとして考える)diff += 2
する。もし入力が正しければdiffは絶対に負の数にはならず、入力の最後まで読んだ時に0になる。
public boolean isValidSerialization(String preorder) {
String[] nodes = preorder.split(",");
int diff = 1;
for (String node: nodes) {
if (--diff < 0) return false;
if (!node.equals("#")) diff += 2;
}
return diff == 0;
}
さらなる解説
これだけだとBTが成り立たない条件を全て満たしているかわからない。確かにBTではリンクに注目すると親から見た子、子から見た親の差が0になり「diffが負にならない」「diffが最後0になる」を満たさなければBTが成立しないことがわかる。しかしこれはBTが成り立つ条件ではなくBTが成り立たない条件なので、これ以外にBTが成り立たない条件が存在しないこと(ケースに漏れがこと)を証明する必要がある。
(加筆予定)
Discussion