题目:. - 力扣(LeetCode)
序列化二叉树的一种方法是使用 前序遍历 。当我们遇到一个非空节点时,我们可以记录下这个节点的值。如果它是一个空节点,我们可以使用一个标记值记录,例如 #
。
例如,上面的二叉树可以被序列化为字符串 "9,3,4,#,#,1,#,#,2,#,6,#,#"
,其中 #
代表一个空节点。
给定一串以逗号分隔的序列,验证它是否是正确的二叉树的前序序列化。编写一个在不重构树的条件下的可行算法。
保证 每个以逗号分隔的字符或为一个整数或为一个表示 null
指针的 '#'
。
你可以认为输入格式总是有效的
- 例如它永远不会包含两个连续的逗号,比如
"1,,3"
。
注意:不允许重建树。
基于栈实现,遍历每个节点字符,入栈。连续的两个'#',可以抵消前面一个节点,兑换成一个'#'。
具体入栈规则:
1)如果遇到的不是'#',直接入栈;
2)如果遇到'#',则看当前栈顶是否也是'#'。
(如果是,则弹出2个字符,压入1个'#'(连续两个'#',则可消掉再前面一个节点,兑成一个'#',入栈);
否则,直接入栈;
兑出来的'#'入栈后,如果满足2),则继续循环2)
方法一:栈
class Solution {
public:bool isValidSerialization(string preorder) {vector<string> stk; // 使用一个数组模拟栈stringstream ss(preorder); // 使用 stringstream与getline 分割字符串string temp;// getline(输入流,暂存从流中读取的字符串,读取终止符)while (getline(ss, temp, ',')){stk.push_back(temp);int len = stk.size();// 用「#」替换 「数字##」while (len >= 3 && stk[len - 1] == "#" && stk[len - 2] == "#" && stk[len - 3] != "#"){stk.pop_back();stk.pop_back();stk.pop_back();stk.push_back("#");len = stk.size();}}// 如果最后模拟栈中只剩一个#,说明是合法的序列return stk.size() == 1 && stk[0] == "#";}
};
方法二:入度出度
class Solution(object):def isValidSerialization(self, preorder):nodes = preorder.split(',')diff = 1for node in nodes:diff -= 1if diff < 0:return Falseif node != '#':diff += 2return diff == 0