***我怎么一题都不会md
题目
https://leetcode-cn.com/problems/verify-preorder-serialization-of-a-binary-tree/
方法一
分析
我们可以定义一个概念,叫做槽位。一个槽位可以被看作「当前二叉树中正在等待被节点填充」的那些位置。
二叉树的建立也伴随着槽位数量的变化。每当遇到一个节点时:
如果遇到了空节点,则要消耗一个槽位;
如果遇到了非空节点,则除了消耗一个槽位外,还要再补充两个槽位。
我们使用栈来维护槽位的变化。栈中的每个元素,代表了对应节点处剩余槽位的数量,而栈顶元素就对应着下一步可用的槽位数量。当遇到空节点时,仅将栈顶元素减 1;当遇到非空节点时,将栈顶元素减 1 后,再向栈中压入一个 2。无论何时,如果栈顶元素变为 0,就立刻将栈顶弹出。
遍历结束后,若栈为空,说明没有待填充的槽位,因此是一个合法序列;否则若栈不为空,则序列不合法。此外,在遍历的过程中,若槽位数量不足,则序列不合法。
代码
class Solution {
public boolean isValidSerialization(String preorder) {
Deque<Integer> stack=new LinkedList<>();
stack.push(1);
int i=0;
int n=preorder.length();
while(i<n){
if(stack.isEmpty()){
return false;
}
if(preorder.charAt(i)==','){
i++;
continue;
}
else if(preorder.charAt(i)=='#'){
i++;
int top=stack.pop()-1;
if(top>0){
stack.push(top);
}
}
else if(Character.isDigit(preorder.charAt(i))){
while(i<n&&Character.isDigit(preorder.charAt(i))){
i++;
}
int top=stack.pop()-1;
if(top>0){
stack.push(top);
}
stack.push(2);
}
}
return stack.isEmpty();
}
}
复杂度
时间复杂度:O(n),其中 n 为字符串的长度。我们每个字符只遍历一次,同时每个字符对应的操作都是常数时间的。
空间复杂度:O(n)。此为栈所需要使用的空间。
空间优化代码
class Solution {
public boolean isValidSerialization(String preorder) {
int slot=1;
int i=0;
int n=preorder.length();
while(i<n){
if(slot==0){
return false;
}
if(preorder.charAt(i)==','){
i++;
continue;
}
else if(preorder.charAt(i)=='#'){
i++;
slot=slot-1;
}
else if(Character.isDigit(preorder.charAt(i))){
while(i<n&&Character.isDigit(preorder.charAt(i))){
i++;
}
slot=slot-1+2;
}
}
return slot==0;
}
}
空间优化复杂度
时间复杂度:O(n),其中 n 为字符串的长度。我们每个字符只遍历一次,同时每个字符对应的操作都是常数时间的。
空间复杂度:O(1)。
方法二
方法三:前序序列建树
class Solution {
int i;
public boolean isValidSerialization(String preorder) {
String[] strings = preorder.split(",");
i = 0;
//构建完整棵树以后,序列化中的所有结点都应被用到,也就是 i == strings.length
return canBuild(strings) && i == strings.length;
}
public boolean canBuild(String[] strings) {
//如果在建立当前结点时发现序列化中没有结点了,那就返回 false
if (i == strings.length) {
return false;
}
//如果当前结点是 null,就返回 true
if (strings[i++].equals("#")) {
return true;
}
//构建左子树和右子树
return canBuild(strings) && canBuild(strings);
}
}