每日打卡:从先序遍历还原二叉树
2020-07-18 04:22
447 查看
打卡: 从先序遍历还原二叉树
心情
《隐秘的角落》电视剧拍得太真实了,每个人都背负着枷锁走在这个世界上。有些时候看着自己的内心,就像是看着一个不相干的人在做着另一个世界的事情。
读题
leetcode: 1028. 从先序遍历还原二叉树
描述:
我们从二叉树的根节点 root 开始进行深度优先搜索。
在遍历中的每个节点处,我们输出 D 条短划线(其中 D 是该节点的深度),然后输出该节点的值。(如果节点的深度为 D,则其直接子节点的深度为 D + 1。根节点的深度为 0)。
如果节点只有一个子节点,那么保证该子节点为左子节点。
给出遍历输出 S,还原树并返回其根节点 root。
测试用例:
输入:“1-2–3--4-5–6--7”
输出:[1,2,5,3,4,6,7]
输入:“1-2–3—4-5–6—7”
输出:[1,2,5,3,null,6,null,4,null,7]
输入:“1-401–349—90–88”
输出:[1,401,null,349,88,90]
提示:
原始树中的节点数介于 1 和 1000 之间。
每个节点的值介于 1 和 10 ^ 9 之间。
先序遍历,二叉树,好熟悉~
思路
1:递归吧
实现
class Solution { public TreeNode recoverFromPreorder(String S) { TreeNode node = null; if (S != null && S.length() > 0) { String num = getNumber(S,"-"); node = new TreeNode(Integer.valueOf(num)); parseNode(node, S.substring(num.length()), "-"); } return node; } /** * 字符串转换为树 * @param node 当前节点 * @param str 左侧树 * @param trim 分割的字符串 * @return */ public String parseNode(TreeNode node, String str, String trim) { if (str.length() > 0) { String resultStr = trimStr(str, trim); //strs[0]必然为空,不为空也不需要处理 //左侧树 if (str.length() - resultStr.length() == trim.length()) { String num = getNumber(resultStr,"-"); node.left = new TreeNode(Integer.valueOf(num)); if (resultStr.length() > num.length()) { str = parseNode(node.left, resultStr.substring(num.length()), trim + "-"); }else{ str = resultStr; } } //右侧树 resultStr = trimStr(str, trim); if (str.length() - resultStr.length() == trim.length()) { String num = getNumber(resultStr,"-"); node.right = new TreeNode(Integer.valueOf(num)); if (resultStr.length() > num.length()) { str = parseNode(node.right, resultStr.substring(num.length()), trim + "-"); }else{ str = resultStr; } } } return str; } /** * 移除字符串前面的指定字符串 * @param str * @param prefix * @return */ public String trimStr(String str, String prefix) { if (str.length() > 0 && str.startsWith(prefix)) { return trimStr(str.substring(prefix.length()), prefix); } else { return str; } } /** * 获取字符串最前面的数值 * @param str * @param prefix * @return */ public String getNumber(String str, String prefix) { if(str.indexOf(prefix)!=-1){ str = str.substring(0,str.indexOf(prefix)); } return str; } }
还是比较清晰的思路,依次处理左节点再处理右节点。
提交
本想着用-分割子集,然后递归分割就能实现结果。结果卡在了第一步,用-分割子集要循环太多次……
标答
class Solution { public TreeNode recoverFromPreorder(String S) { // 存储当前节点的路径 Deque<TreeNode> path = new LinkedList<TreeNode>(); // 存储字符串中的位置 int pos = 0; while (pos < S.length()) { // 获取当前层数 int level = 0; while (S.charAt(pos) == '-') { ++level; ++pos; } // 获取节点值 int value = 0; while (pos < S.length() && Character.isDigit(S.charAt(pos))) { value = value * 10 + (S.charAt(pos) - '0'); ++pos; } // 构造当前节点 TreeNode node = new TreeNode(value); if (level == path.size()) { //如果当前节点的深度==当前路径长度(前一个节点是当前节点的父节点) if (!path.isEmpty()) { //如果不是第一个节点,前一个节点的左子节点为当前节点 path.peek().left = node; } }else { //如果当前节点的深度!=当前路径长度(前一个节点不是当前节点的父节点) while (level != path.size()) { //通过queue弹出其他子节点,找到当前节点的父节点 path.pop(); } // 找到父节点,因为此时左子节点已确定,所以赋值给右子节点 path.peek().right = node; } // 放入queue中 path.push(node); } // 全部弹出,只剩根节点 while (path.size() > 1) { path.pop(); } // 返回根 return path.peek(); } }
相关文章推荐
- 7-5 还原二叉树 (25 分)(二叉树,根据 中序遍历 和 先序遍历)
- 每天一道LeetCode-----根据先序遍历和中序遍历还原二叉树
- (13) 1028. 从先序遍历还原二叉树
- 每日编程9之二叉树的先序遍历递归版本
- 二叉树的应用-先序遍历中序遍历还原二叉树
- 通过先序遍历和中序遍历后的序列还原二叉树(实现方法)
- 二叉树的先序遍历、中序遍历、后续遍历和二叉树还原
- 每日编程10之二叉树的先序遍历的非递归版本
- LeetCode之从先序遍历还原二叉树
- 已知二叉树的先序遍历(preorder)和中序遍历(inorder) 或 中序和后序(postorder),还原该二叉树
- 二叉树先序遍历
- 前序/后序+中序还原二叉树
- 数据结构实验之二叉树四:还原二叉树
- c++实现二叉树的先序遍历,中序遍历,后序遍历(递归方法)及运行实例结果
- 每日一题——二叉树的遍历
- 每日一题——求二叉树叶子节点个数,第K层节点个数
- 求二叉树的先序遍历
- 利用先序遍历创建二叉树的后序遍历序列(0979)
- 通过输入二叉树先序遍历和中序遍历,输出其后序遍历
- Leetcode打卡 对称二叉树