序列化二叉树的一种方法是使用 前序遍历 。当我们遇到一个非空节点时,我们可以记录下这个节点的值。如果它是一个空节点,我们可以使用一个标记值记录,例如 #。
例如,上面的二叉树可以被序列化为字符串 “9,3,4,#,#,1,#,#,2,#,6,#,#”,其中 # 代表一个空节点。
给定一串以逗号分隔的序列,验证它是否是正确的二叉树的前序序列化。编写一个在不重构树的条件下的可行算法。
保证 每个以逗号分隔的字符或为一个整数或为一个表示 null 指针的 ‘#’ 。
你可以认为输入格式总是有效的
例如它永远不会包含两个连续的逗号,比如 “1,3” 。
注意:不允许重建树。
示例 1:
输入: preorder = “9,3,4,#,#,1,#,#,2,#,6,#,#”
输出: true
示例 2:
输入: preorder = “1,#”
输出: false
示例 3:
输入: preorder = “9,#,#,1”
输出: false
提示:
1 <= preorder.length <= 104
preorder 由以逗号 “,” 分隔的 [0,100] 范围内的整数和 “#” 组成
题意:
给出一段字符串序列,问这段序列是否是一段合法的前序遍历序列,是的话返回True,否则返回False
思路:
前提是这道题已经说了,不可以构建树,当然了,就算不说的话,在座聪明的各位应该也不会构树。
因为他每个null的节点,都是以 # 结尾的,那这一点就会让我们找到灵感。
当我们从前遍历到某一个位置的时候,该位置为数字,就说明他是可以继续向前走的,当该位置是#,就说明这个位置走不了了,只能往回走。
那我们首先定义一个num,表示我们当前可以走的路的数量,因为我们开始一定是可以走根节点的,然后开始从根节点开始遍历,当前位置是数字,就num++,说明可以往下面走;当前如果是#,num–,说明无法往下面走,回退一步,看看是否可以往右边走。
那最后如果num==0,说明是一个正确的前序遍历,否则就不是。
特别的,如果还没走完num就已经==0了,也说明这不是一个正确的前序遍历/。
代码:
class Solution {
public:
bool isValidSerialization(string preorder) {
vector<string> pre;
int n = preorder.size();
string str;
for(int i = 0 ; i < n ; i++){
if(preorder[i] != ',')
str += preorder[i];
else{
pre.push_back(str);
str = "";
}
}
pre.push_back(str);
n = pre.size();
int num = 1;
for(int i = 0 ; i < n ; i++){
cout << pre[i] << endl;
if(pre[i] == "#"){
if(num <= 0)
{cout << num << endl ; return false;}
else
num--;
}
else
num++;
if(num == 0 && i != n-1)
{cout << num << endl;return false;}
cout << num << endl;
}
cout << num << endl;
return num==0;
}
};