- 331 验证二叉树的前序序列化
- 来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/verify-preorder-serialization-of-a-binary-tree - 序列化二叉树的一种方法是使用前序遍历。当我们遇到一个非空节点时,我们可以记录下这个节点的值。如果它是一个空节点,我们可以使用一个标记值记录,例如 #。
_9_
/ \
3 2
/ \ / \
4 1 # 6
/ \ / \ / \
# # # # # #
例如,上面的二叉树可以被序列化为字符串 “9,3,4,#,#,1,#,#,2,#,6,#,#”,其中 # 代表一个空节点。
给定一串以逗号分隔的序列,验证它是否是正确的二叉树的前序序列化。编写一个在不重构树的条件下的可行算法。
每个以逗号分隔的字符或为一个整数或为一个表示 null 指针的 ‘#’ 。
你可以认为输入格式总是有效的,例如它永远不会包含两个连续的逗号,比如 “1,3” 。
示例 1:
输入: "9,3,4,#,#,1,#,#,2,#,6,#,#"
输出: true
解题思路:【python3】(1) 辅助栈: 遇到数值压入栈,遇到‘#’弹出栈顶元素(前提: 栈不为空),注意到最后一个一定是‘#’且其数量比数值数量多1,用num_nodes记录遍历节点的数量, 当遇到‘#’时,若栈为空且num_nodes + 1==preorder节点数即遍历至字符串的末尾,返回true,否则返回false。 (2)槽位: 只要存在一非数值节点,其必存在两个子节点,用槽位slots记录节点数,初始为 1,遍历preorder所有节点,每遍历一次slots减 1,若该节点为非空节点,slots加2,若slots<0,则返回false。最终如果slots=0返回true。
Notes 1 : 二叉树一个重要的性质是叶子节点的数量是非叶子节点数量之和+1.
Notes 2 : 刚开始遍历字符串的时候,用的for s in preorder
,问题是若节点数值为多位数,则无法得到正确节点数。学到了--------preorder.split(',')
-----------得到以逗号间隔的若干字符组成的list,例如([‘9’, ‘#’, ‘92’, ‘#’, ‘#’])。
【c++】辅助栈: 只是因为没有找到类似python里split这种好用的函数,就换了一种解决方式,基本思想一致。遍历preorder,遇到数值节点将0压入栈(压入随意什么数值),为了解决多位数的问题,在遇到‘,'或者下标超出范围之前,i++,跳过这些位到逗号后的下一个节点。遇到‘#’,若栈不为空弹出栈顶元素,为空判断是否遍历至字符串结尾,是返回true,否则false。
Notes 3 : while条件里要加 i 范围限制,不然就死循环了.
# python 3
class Solution:
def isValidSerialization(self, preorder: str) -> bool:
# solution 1:
# stack = []
# num_nodes = 0
# print(preorder.split(','))
# for s in preorder.split(','):
# if s == '#' :
# if stack:
# stack.pop()
# num_nodes +=1
# else:
# if num_nodes+1== len(preorder.split(',')): return True
# else: return False
# else:
# stack.append(s)
# num_nodes +=1
# return False
# solution 2:
stack = []
if len(preorder.split(',')) == 0: return True
slots = 1
for node in preorder.split(','):
slots -= 1
if slots<0 : return False
if node !='#' : slots += 2
return slots==0
// c++
class Solution {
public:
bool isValidSerialization(string preorder) {
if (preorder.empty()) return true;
stack<int> my_stack;
for (int i =0 ; i< preorder.size(); ++i){
if (preorder[i] == '#'){
if(!my_stack.empty()) my_stack.pop();
else if (i+1 == preorder.size()) return true;
else return false;
}
else if(preorder[i]!=','){
// while条件里要加 i 范围限制,不然就死循环了
while(preorder[i]!=',' && i< preorder.size()) ++i;
my_stack.push(0);
}
}
return false;
}
};