LeetCode 606. 根据二叉树创建字符串
606. 根据二叉树创建字符串
Solution
思路:最开始的思路就是简单的先序遍历,然后就可以得到带有空括号的字符串,再处理即可,代码都写了,然后发现有问题,还是在遍历的时候控制比较好,然后就开始无脑乱改,发现逻辑是通的,不过代码已经成狗屎了,删了重新写,梳理逻辑,1Y
主要是叶节点和非叶节点的)
,应该是叶节点不处理, 统一回退处理,然后存在孩子之一必有(
,然后就是转右孩子的细节)(
class Solution {
StringBuilder str = new StringBuilder();
public String tree2str(TreeNode root) {
if (root == null) return "";
preOrder(root);
return str.toString();
}
void preOrder(TreeNode p) {
str.append(p.val);
if (p.left == p.right && p.left == null) { //处理叶节点 不需要这里加')';
return;
}
if (p.left != null || p.right != null) { //左边不能省 所有存在孩子之一就要有'('
str.append('(');
}
if (p.left != null) { // 左孩子
preOrder(p.left);
}
if (p.right != null) { // 转右孩子的时候 要“封好”又要“开始”
str.append(')(');
preOrder(p.right);
}
str.append(')'); //回退的时候加')'
}
}
题解代码感觉很离谱 又很强。效率没那么好,顺带复习一下迭代版本。
class Solution {
public String tree2str(TreeNode root) {
if (root == null) return "";
if (root.left == null && root.right == null) return Integer.toString(root.val);
if (root.right == null) return new StringBuilder().append(root.val).append('(').append(tree2str(root.left)).append(')').toString();
return new StringBuilder().append(root.val).append('(').append(tree2str(root.left)).append(")(").append(tree2str(root.right)).append(')').toString();
}
}
迭代:
不和常规的版本一样,栈内元素一直保留,同时记录遍历过的节点,如果该节点遍历过,再出栈,并封上)
,每次入栈先右后左,然后如果左空右不空就加上()
,注意根节点的特殊情况。
class Solution {
public String tree2str(TreeNode root) {
StringBuilder ans = new StringBuilder();
Deque<TreeNode> stack = new ArrayDeque<>();
Set<TreeNode> vis = new HashSet<>();
stack.push(root);
while (!stack.isEmpty()) {
TreeNode node = stack.peek();
if (!vis.add(node)) {
if (node != root) {
ans.append(')');
}
stack.pop();
} else {
vis.add(node);
if (node != root) {
ans.append('(');
}
ans.append(node.val);
if (node.left == null && node.right != null) {
ans.append("()");
}
if (node.right != null) {
stack.push(node.right);
}
if (node.left != null) {
stack.push(node.left);
}
}
}
return ans.toString();
}
}
埋骨何须桑梓地,人生无处不青山