题目描述
序列化二叉树的一种方法是使用前序遍历。当我们遇到一个非空节点时,我们可以记录下这个节点的值。如果它是一个空节点,我们可以使用一个标记值记录,例如 #。
例如,上面的二叉树可以被序列化为字符串 "9,3,4,#,#,1,#,#,2,#,6,#,#",其中 # 代表一个空节点。
给定一串以逗号分隔的序列,验证它是否是正确的二叉树的前序序列化。编写一个在不重构树的条件下的可行算法。
每个以逗号分隔的字符或为一个整数或为一个表示 null 指针的 '#' 。
你可以认为输入格式总是有效的,例如它永远不会包含两个连续的逗号,比如 "1,,3" 。
示例 1:
输入: "9,3,4,#,#,1,#,#,2,#,6,#,#" 输出: true 示例 2:
输入: "1,#" 输出: false 示例 3:
输入: "9,#,#,1" 输出: false
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/ve… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题解思路
- 每遇到一个数字,他需要两个子节点来填充,且他本身填充了一个父节点的坑位。number ==> slots + 2 - 1。
- 每遇到一个“#”,他不需要子节点填充,且他本身填充了一个父节点的坑位。# ==> slots - 1。
- 由于根节点没有父节点,其自身不占坑位,所以root ==> slots + 2。
- 当还有节点,但却没有坑位时slots === 0,说明该树存在多余节点返回false。
- 当所有节点遍历完但slots !== 0,说明还有未填满的坑位,返回false。
题解代码
* @lc app=leetcode.cn id=331 lang=javascript
*
* [331] 验证二叉树的前序序列化
*/
// @lc code=start
/**
* @param {string} preorder
* @return {boolean}
*/
var isValidSerialization = function(preorder) {
//坑位,
//出现数字时,填充了一个父节点所需的坑位,但自身又需要两个坑位来填充slots = slots - 1 + 2
//出现“#"时,填充一个父节点坑位,自身不需要新的坑位来填充slots = slots - 1
let slots = 0;
let treeNodes = preorder.split(',');//字符串转去掉","的数组,方便遍历
for (let i = 0; i < treeNodes.length; i++) {
if (slots === 0 && i !== 0) return false;//如果没有坑位循环还在继续说明节点有多余
if (i === 0) {
if (treeNodes[i] !== "#") {
slots += 2;//根节点没有父节点,不需要消耗坑位,slots = slots + 2
}else if (treeNodes[i] === "#" && treeNodes.length > 1) {
//根节点为#说明不需要坑位,但如果字符串长度大于1,说明有多余节点
//此时可直接返回结果节省不必要的循环
return false;
}
}
else if (treeNodes[i] !== "#") {
slots++;//slots = slots - 1 + 2; 遇到数字本身是填了一个坑,但自身又需要两个坑
}else{
slots--;//遇到#就填了一个坑,因为#下不需要子节点了
}
}
return slots === 0;
};
// @lc code=end