前言
昨天写了一篇题解是[LeetCode94题二叉树的中序遍历] | 刷题打卡,这篇题解了给大家简单介绍了二叉树的几种遍历方式,为什么叫前序、中序、后序遍历,有兴趣的或者想要了解的可以先去看下😄😄😄
题目描述
题目地址:331. 验证二叉树的前序序列化
序列化二叉树的一种方法是使用前序遍历。当我们遇到一个非空节点时,我们可以记录下这个节点的值。如果它是一个空节点,我们可以使用一个标记值记录,例如 #。
_9_
/ \
3 2
/ \ / \
4 1 # 6
/ \ / \ / \
# # # # # #
例如,上面的二叉树可以被序列化为字符串 "9,3,4,#,#,1,#,#,2,#,6,#,#",其中 # 代表一个空节点。
给定一串以逗号分隔的序列,验证它是否是正确的二叉树的前序序列化。编写一个在不重构树的条件下的可行算法。
每个以逗号分隔的字符或为一个整数或为一个表示 null 指针的 '#' 。
你可以认为输入格式总是有效的,例如它永远不会包含两个连续的逗号,比如 "1,,3" 。
示例 1:
输入: "9,3,4,#,#,1,#,#,2,#,6,#,#"
输出: true
示例 2:
输入: "1,#"
输出: false
示例 3:
输入: "9,#,#,1"
输出: false
解题思路
题目给定了一串以逗号分割的序列preorder,要求验证preorder是不是正确的二叉树的前序序列化,不能重构树。
在题目描述里我们知道了二叉树的前序序列化的含义,在树中,所有节点的入度之和等于出度之和。所以我们可以根据这个特点判断输入序列是否为有效的!
在一棵二叉树中:
1、每个空节点( "#" )会提供 0 个出度和 1 个入度。
2、每个非空节点会提供 2 个出度和 1 个入度。
所以,我们先将preorder转成数组nodes,定义一个dif = 1来计算度数。
我们加入一个非空节点时,都会先减去一个入度,再加上两个出度。但是由于根节点没有父节点,所以其入度为 0,出度为 2。因此 diff 初始化为 1,是为了在加入根节点的时候,先减去一个入度,再加上两个出度,此时 diff 正好应该是2.
要验证二叉树preorder,就要遍历nodes,每个节点都累加 dif = 出度 - 入度 。在遍历到任何一个节点的时候,要求dif > 0,原因是还没遍历到该节点的子节点,所以此时的出度应该大于等于入度。当所有节点遍历完成之后,整棵树的dif === 0 。
解题代码
/**
* @param {string} preorder
* @return {boolean}
*/
var isValidSerialization = function(preorder) {
let nodes = preorder.split(',');
let dif = 1;
for (node of nodes) {
dif -= 1;
if (dif < 0) {
return false;
}
if (node !== '#') {
dif += 2;
}
}
return dif === 0;
};
刷题打卡记录
这里是之前的刷题打卡记录,大家有兴趣的可以看下,如果有什么不同的见解和看法或者觉得有什么错误的,欢迎在评论区留言!🙏🙏🙏
[LeetCode0303题区域和检索 - 数组不可变] | 刷题打卡
[LeetCode0304题二维区域和检索 - 矩阵不可变] | 刷题打卡
[LeetCode236题二叉树的最近公共祖先] | 刷题打卡
[LeetCode1124题表现良好的最长时间段] | 刷题打卡
[LeetCode1047题删除字符串中的所有相邻重复项] | 刷题打卡
[LeetCode1438题绝对差不超过限制的最长连续子数组] | 刷题打卡
总结
加油!hxdm!!!💪💪💪
本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情