验证二叉树的前序序列化的思路探讨与源码
验证二叉树的前序序列化的题目如下图,该题属于栈类和二叉树类型的题目,主要考察对于搜索方法的使用和树结构的理解。本文的题目作者想到2种方法,分别是栈方法和入度出度方法,其中栈方法使用Java进行编写,而入度出度方法使用Python进行编写,当然这可能不是最优的解法,还希望各位大佬给出更快的算法。
本人认为该题目可以使用栈方法的思路进行解决,首先计算字符串的长度,并初始化一个双端队列,并压入一个元素1。开始遍历循环,当双端队列是空的时候就直接返回否的结果,当遇到字符值是逗号就直接跳过,当字符值是’#'的时候就将双端队列的头部元素取出并减去1,再判断是否大于0,如果是则放回双端队列的头部;否则就将栈顶元素减去1后再压入一个2,以此遍历循环,直到最后遍历结束判断双端队列是否为空并返回判断结果。那么按照这个思路我们的Java代码如下:
#喷火龙与水箭龟
class Solution {
public boolean isValidSerialization(String preorder) {
int preorderLen = preorder.length();
int ir = 0;
Deque<Integer> stackList = new LinkedList<Integer>();
stackList.push(1);
while (ir < preorderLen) {
if (stackList.isEmpty()) {
return false;
}
if (preorder.charAt(ir) == ',') {
ir = ir + 1;
} else if (preorder.charAt(ir) == '#'){
int topNum = stackList.pop() - 1;
if (topNum > 0) {
stackList.push(topNum);
}
ir = ir + 1;
} else {
while (ir < preorderLen && preorder.charAt(ir) != ',') {
ir = ir + 1;
}
int topNum = stackList.pop() - 1;
if (topNum > 0) {
stackList.push(topNum);
}
stackList.push(2);
}
}
return stackList.isEmpty();
}
}
显然,我们看到栈方法的效果还可以,同时还可以使用入度出度的方法解决。首先按英文逗号将字符串进行分割得到数组,初始化一个标记值。开始遍历循环数组,将标记值减去1,然后判断标记值是否小于0,如果是就直接返回否的结果。再次判断 当前字符值是否不等于’#'的值,如果是就将标记值加上2,按照这个思路进行循环直到遍历结束,最终判断标记值是否等于0,并返回判断结果。所以按照这个思路就可以解决,下面是Python代码:
#喷火龙与水箭龟
class Solution(object):
def isValidSerialization(self, preorder):
vex = preorder.split(',')
resNum = 1
for v in vex:
resNum = resNum - 1
if(resNum < 0):
return False
if(v != '#'):
resNum = resNum + 2
return resNum == 0
从结果来说Java版本的栈方法的效率还可以,而Python版本的入度出度方法的速度也还不错,但应该是有更多的方法可以进一步提速的,希望朋友们能够多多指教,非常感谢。