我就想练练前序遍历二叉树
Date Created: Mar 12, 2021 10:58 AM
Status: 要学习的
331. 验证二叉树的前序序列化
通过阅读题目发现最近对二叉树的联系比较少,所以准备用最直接的方法来做。
这面就想通过将数组还原成二叉树的方法,来判断数组是否是正确的。
起初是想就看数组能不能正确的通过前序方法来还原出来二叉树。就可以直接判断了。(后来才清楚并不是这面简单)
下一步就开始准备还原二叉树的材料了。
构建树节点
class Tree{
String value;//这块用string 就是想通过string的.split(“,”) 直接使用了
Tree left;
Tree right;
public Tree() {
}
public Tree(String value) {
this.value = value;
}
}
下一步…忘记了
复习下二叉树的前序遍历模板
// 简单的理解下 就是先打印根,再打印左节点,接下来是右节点。那么复制或者是重建也是这个顺序
public void preOrderTraverse1(TreeNode root) {
if (root != null) {
System.out.print(root.val + "->");
preOrderTraverse1(root.left);
preOrderTraverse1(root.right);
}
}
那么下一步需要准备的是一个数据源(这里准备用一个可变长度的,用一个就少一个的数据结构,懒着记具体坐标了哈 我这面准备使用java的LinkedList().);
数据源准备
String[] split = preorder.split(",");
Deque<String> deque = new LinkedList<>();
for (String s : split) {
deque.offer(s);
}
这一步也做完了下一步就是修改 将遍历的改成 创建二叉树;
通过前序的方式创建二叉树
// 入参本来想只用一个Deque了 但是咱要用递归嘛 所以就加上了一个Tree
private Tree getTree(Deque<String> strings,Tree tree){
if (!strings.isEmpty()){ //递归终止条件
if ("#".equals(strings.peek())) { //判断是不是一个岔到头了
strings.pop(); //记得要把“#” 删除哈 第一次忘记删除了,就返回了一个岔
return tree;
}
tree = new Tree(strings.pop()); //赋值根节点
tree.left = getTree(strings, tree.left); //赋值左节点
tree.right = getTree(strings, tree.right); //赋值右节点
}
return tree;
}
好了 其实到这步对前序 复习的就差不多了,
下面开始解题哈哈
题目分析
是否能通过前序方式创建二叉树?
问题是咱们都创建好了,咋知道咱们创建的和数组提供的是一个呢?
比如 数组提供了 包含 6个节点的二叉树。 咱们通过它创建了 4个节点的。就说明他提供的是有问题的。我是这样想的。
所以就添加了变量来记录节点数量。要不然还要遍历就麻烦了。
private static Tree getTree(Deque<String> strings,Tree tree){
if (!strings.isEmpty()){
if ("#".equals(strings.peek())) {
strings.pop();
return tree;
}
num++; //这里添加了一个全局变量来记录-》节点数
tree = new Tree(strings.pop());
tree.left = getTree(strings, tree.left);
tree.right = getTree(strings, tree.right);
}
return tree;
}
之后在修改一下主方法
主方法
public Boolean isValidSerialization(String preorder) {
String[] split = preorder.split(",");
Deque<String> deque = new LinkedList<>();
int nodeNum = 0;
for (String s : split) {
deque.offer(s);
if (!"#".equals(s)) {
nodeNum++;
}
}
getTree(deque, null);//这里都没用上创建好的二叉树,重点是练习下哈 所以用不用上无所谓 哈哈
return nodeNum == num ;
}
自信满满提交了,显然存在问题
被测试用例打脸了 【1,#】
想了想发现,节点数对了 但是 null 的数量不对。
一个节点 对应两个null
两个节点 对应三个null
三个节点 对应四个null
修改后的主方法
public static Boolean isValidSerialization(String preorder) {
String[] split = preorder.split(",");
Deque<String> deque = new LinkedList<>();
int len = split.length;
int nodeNum = 0;
int nullNum = 0; //记录下null节点的数量
for (String s : split) {
deque.offer(s);
if (!"#".equals(s)) {
nodeNum++;
}
}
nullNum = len - nodeNum;
getTree(deque, null);
return (nodeNum == num)&&(nullNum == nodeNum+1) ; //添加判断
}
过啦
复习就到这里啦。