- 题目
序列化二叉树的一种方法是使用前序遍历。当我们遇到一个非空节点时,我们可以记录下这个节点的值。如果它是一个空节点,我们可以使用一个标记值记录,例如 #。
_9_
/ \
3 2
/ \ / \
4 1 # 6
/ \ / \ / \
# # # # # #
例如,上面的二叉树可以被序列化为字符串 "9,3,4,#,#,1,#,#,2,#,6,#,#",其中 # 代表一个空节点。
给定一串以逗号分隔的序列,验证它是否是正确的二叉树的前序序列化。编写一个在不重构树的条件下的可行算法。
每个以逗号分隔的字符或为一个整数或为一个表示 null 指针的 '#' 。
你可以认为输入格式总是有效的,例如它永远不会包含两个连续的逗号,比如 "1,,3" 。
- 示例
输入: "9,3,4,#,#,1,#,#,2,#,6,#,#"
输出: true
输入: "1,#"
输出: false
输入: "9,#,#,1"
输出: false
3.代码实现
思路:正确序列化要求每个数字节点的左,右孩子都会有相应标识,要么为“#”要么为数字。
a.若为数字,则入栈,取序列下一个元素,下一个元素应为栈顶元素的左孩子,成功取到,置当前元素为栈顶元素的左孩子,继续上述步骤,直到为“#”结束;(若不能取到下一个元素,表示当前节点左孩子无标识)
b.栈顶元素左孩子“#”,则下一个元素应为栈顶元素的右孩子,假定栈顶元素右孩子会有标识(即可以成功取到序列当中下一个元素),弹出栈顶元素,置当前元素为栈顶右孩子;继续a步骤。(不能取到序列当中的元素,表示栈顶元素右孩子无标识)
c.上述a,b操作无任何异常出现,且栈为空,序列刚好到末尾可认定为正确的序列化。
public class Solution {
//正确序列化要求每个数字节点的左,右孩子都会有相应标识,要么为“#”要么为数字。
public boolean isValidSerialization(String preorder) {
int i = 0;
Stack<String> stack = new Stack<>();
String[] nums = preorder.split(",");
String c = nums[i];
while (!c.equals("#")||!stack.empty()){
while (!c.equals("#")){
stack.push(c);
//取下一个序列
if(i<nums.length-1){
i++;
c = nums[i];
}else{
//表示当前节点左孩子无标识
return false;
}
}
if (!stack.empty()){
//弹出栈顶元素,先假定其右孩子有相应标识
stack.pop();
//假定成立
if(i<nums.length-1){
i++;
c = nums[i];
}else{
//假定不成立
return false;
}
}
}
return stack.empty()&&i==nums.length-1;
}
}