想要精通算法和SQL的成长之路 - 验证二叉树的前序序列化
- 前言
- [一. 验证二叉树的前序序列化](#一. 验证二叉树的前序序列化)
前言
一. 验证二叉树的前序序列化
思路(参考负雪明图):
- 首先我们看题目所给的字符串,是一个先序遍历的结果。也就是说:父节点--> 左节点-->右节点,这么一个遍历顺序。
- 那么我们可以先校验左子树是否是合法的,再判断右子树是否合法。从而决定当前树是否有效。
如果一个节点是叶子节点,它的两个孩子必定是空,对于题目而言就是:
否则,一个非叶子节点存在两种可能:
- 两个孩子都非空。
- 一个孩子为空,一个孩子非空。
如图:
核心思路如下:
- 如果遇到叶子节点(两个孩子都为空)的时候,将当前叶子节点看做是一个空节点。
- 那么对于该叶子节点的父节点而言:两个孩子都变成了空节点,那么父节点就是叶子节点。以此往上递推。即
4,#,#
变成#
- 例如:[9,#2,#,
6,#,#
] => [9,#,2,#,#
] => [9,#,#
] => [#]。
我们用栈来遍历这个前序遍历的结果,用自底向上的特性去操作:
- 从左往右,元素不断入栈。
- 当栈顶的前三个元素满足以下条件:前两个都是#,第三个非#。此时弹出前三个元素,再入一个#号作为替代。
4,#,#
变成#
的一个体现。 - 最终遍历完毕,如果整个栈中,还剩下一个元素,并且是
#
号, 说明二叉树的前序遍历是有效的。
java
public boolean isValidSerialization(String preorder) {
LinkedList<String> stack = new LinkedList<>();
for (String str : preorder.split(",")) {
stack.push(str);
// 如果栈顶的前两个元素都是#号,并且第三个元素非 # 号,那么弹出前三个元素,并入一个#号
while (stack.size() >= 3
&& "#".equals(stack.get(0))
&& "#".equals(stack.get(1))
&& !"#".equals(stack.get(2))) {
stack.pop();
stack.pop();
stack.pop();
stack.push("#");
}
}
return stack.size() == 1 && "#".equals(stack.get(0));
}