Medium
题目描述
序列化二叉树的一种方法是使用前序遍历。当我们遇到一个非空节点时,我们可以记录下这个节点的值。如果它是一个空节点,我们可以使用一个标记值记录,例如 #。
例如,上面的二叉树可以被序列化为字符串 "9,3,4,#,#,1,#,#,2,#,6,#,#",其中 # 代表一个空节点。
给定一串以逗号分隔的序列,验证它是否是正确的二叉树的前序序列化。编写一个在不重构树的条件下的可行算法。
保证 输入格式总是有效的,例如它永远不会包含两个连续的逗号,比如 "1,,3" 。
示例 1:
输入: preorder = "9,3,4,#,#,1,#,#,2,#,6,#,#"
输出: true
示例 2:
输入: preorder = "1,#"
输出: false
示例 3:
输入: preorder = "9,#,#,1"
输出: false
提示:
1 <= preorder.length <= 10^4preorder由整数(在范围[0, 100]内)和'#'组成,用逗号','分隔
解题思路
思路分析
这道题有两种主要解法:
方法一:度数统计法(推荐)
将二叉树看作图,每个节点最多有一个入度和两个出度。对于前序遍历:
- 每个非空节点贡献 1 个入度(除了根节点)和 2 个出度
- 每个空节点(#)贡献 1 个入度,0 个出度
整个过程中,出度应该始终 ≥ 入度,最后两者相等。我们可以用一个变量 diff = 出度 - 入度 来跟踪:
- 遇到非空节点:diff += 1(+2出度-1入度,根节点无入度所以是+2)
- 遇到空节点:diff -= 1(+0出度-1入度)
- 过程中 diff 不能小于 0
- 最终 diff 应该等于 0
方法二:栈模拟法
使用栈模拟递归构建过程,遇到连续的空节点时进行回溯。具体是将连续的"值,#,#“模式替换为单个”#",直到无法继续替换。
度数统计法更简洁高效,时间复杂度 O(n),空间复杂度 O(1)。
代码实现
class Solution {
public:
bool isValidSerialization(string preorder) {
int diff = 1; // 出度 - 入度
istringstream iss(preorder);
string node;
while (getline(iss, node, ',')) {
diff--; // 每个节点都有入度(除了第一个根节点,但我们初始化为1来处理)
if (diff < 0) return false;
if (node != "#") {
diff += 2; // 非空节点有两个出度
}
}
return diff == 0;
}
};
class Solution:
def isValidSerialization(self, preorder: str) -> bool:
diff = 1 # 出度 - 入度
nodes = preorder.split(',')
for node in nodes:
diff -= 1 # 每个节点都有入度
if diff < 0:
return False
if node != '#':
diff += 2 # 非空节点有两个出度
return diff == 0
public class Solution {
public bool IsValidSerialization(string preorder) {
int diff = 1; // 出度 - 入度
string[] nodes = preorder.Split(',');
foreach (string node in nodes) {
diff--; // 每个节点都有入度
if (diff < 0) return false;
if (node != "#") {
diff += 2; // 非空节点有两个出度
}
}
return diff == 0;
}
}
var isValidSerialization = function(preorder) {
const nodes = preorder.split(',');
let slots = 1;
for (let i = 0; i < nodes.length; i++) {
slots--;
if (slots < 0) return false;
if (nodes[i] !== '#') slots += 2;
}
return slots === 0;
};
复杂度分析
| 复杂度类型 | 度数统计法 | 栈模拟法 |
|---|---|---|
| 时间复杂度 | O(n) | O(n) |
| 空间复杂度 | O(1) | O(n) |
其中 n 为字符串长度。度数统计法是最优解法,只需要一次遍历且使用常数额外空间。