一、前言
遍历字符串时,犯了一个错误,应该是以,为分隔符,来遍历。
式子1:
for(let i = 0; i < str.length; ++i) {
if(str[i]) === ',') continue
console.log(str[i])
}
式子2:
const strArr = str.split(',')
for(let i = 0; i < strArr.length; ++i) {
console.log(strArr[i])
}
假设str = '3,4,5,6',那么上面的式子是等价的,但是如果str='30,40,50,60',那么很显然不相等。
这是我这次遇见的错误,记录下。
二、题目描述
原谅我比较懒,我直接从leetcode截图,欲知更加清楚的描述,请看leetcode题目链接
三、分析
- 事件与事件是完全包含关系, 用栈解决。 每个非空节点都有左右子节点。从根节点往下验证,需要验证每个节点,子节点验证成功,才能验证跟根节点,属于包含关系
- 每个非空几点都有两个子节点。故遇见一个非空节点,先抵掉了上层的一个子节点位置,然后自身又增加了两个子节点位置,故 栈顶-1, 压栈2
- 当自身的两个子节点都被占了位置,此时栈顶为0,需要执行出栈操作
- 遇见空节点,首先会抵掉上层的一个子节点的位置,但是由于空节点没有子节点,故不需要压栈
四、代码
/**
* @param {string} preorder
* @return {boolean}
*/
const isValidSerialization = function(preorder) {
// 初始化栈, 初始化为1,可减少一些边界判断
const stack = [1]
// 将字符串转换成数组,直接遍历字符串可能会遇见‘92’这种多位数,也是为了减少一些边界,当然也可以直接遍历字符串,遇到数字,还要继续遍历直到找到‘,’号
const preorderArr = preorder.split(',')
// 遍历上面转换的数组
for(let i = 0; i < preorderArr.length; ++i) {
// 还没遍历完数组,栈为空时,代表这是错误的序列化
if(!stack.length) return false
// 遇见#号,栈顶元素-1,遇见非#号,栈顶元素-1,再入栈2。 注意这期间如果栈顶为0时,需要出栈
if(preorderArr[i] === '#') {
// 栈顶-1
stack[stack.length - 1]--
// 栈顶-1后判断栈顶是否为0,为0出栈
(stack[stack.length - 1] === 0) && stack.pop()
} else {
// 栈顶-1
stack[stack.length - 1]--
// 栈顶-1后判断栈顶是否为0,为0出栈
(stack[stack.length - 1] === 0) && stack.pop()
// 入栈2
stack.push(2)
}
}
// 遍历处理后,栈为空,代表时正确的二叉树前序序列
return !stack.length
}