You need to construct a binary tree from a string consisting of parenthesis and integers.

The whole input represents a binary tree. It contains an integer followed by zero, one or two pairs of parenthesis. The integer represents the root's value and a pair of parenthesis contains a child binary tree with the same structure.

You always start to construct the left child node of the parent first if it exists.

Example:

Input: "4(2(3)(1))(6(5))"
Output: return the tree root node representing the following tree: 4
/ \
2 6
/ \ /
3 1 5

Note:

  1. There will only be '('')''-' and '0' ~ '9' in the input string.
  2. An empty tree is represented by "" instead of "()".

这道题让我们根据一个字符串来创建一个二叉树,其中结点与其左右子树是用括号隔开,每个括号中又是数字后面的跟括号的模式,这种模型就很有递归的感觉,所以我们当然可以使用递归来做。首先我们要做的是先找出根结点值,我们找第一个左括号的位置,如果找不到,说明当前字符串都是数字,直接转化为整型,然后新建结点返回即可。否则的话从当前位置开始遍历,因为当前位置是一个左括号,我们的目标是找到与之对应的右括号的位置,但是由于中间还会遇到左右括号,所以我们需要用一个变量 cnt 来记录左括号的个数,如果遇到左括号,cnt 自增1,如果遇到右括号,cnt 自减1,这样当某个时刻 cnt 为0的时候,我们就确定了一个完整的子树的位置,那么问题来了,这个子树到底是左子树还是右子树呢,我们需要一个辅助变量 start,当最开始找到第一个左括号的位置时,将 start 赋值为该位置,那么当 cnt 为0时,如果 start 还是原来的位置,说明这个是左子树,我们对其调用递归函数,注意此时更新 start 的位置,这样就能区分左右子树了,参见代码如下:

解法一:

class Solution {
public:
TreeNode* str2tree(string s) {
if (s.empty()) return NULL;
auto found = s.find('(');
int val = (found == string::npos) ? stoi(s) : stoi(s.substr(, found));
TreeNode *cur = new TreeNode(val);
if (found == string::npos) return cur;
int start = found, cnt = ;
for (int i = start; i < s.size(); ++i) {
if (s[i] == '(') ++cnt;
else if (s[i] == ')') --cnt;
if (cnt == && start == found) {
cur->left = str2tree(s.substr(start + , i - start - ));
start = i + ;
} else if (cnt == ) {
cur->right = str2tree(s.substr(start + , i - start - ));
}
}
return cur;
}
};

下面这种解法使用迭代来做的,借助栈 stack 来实现。遍历字符串s,用变量j记录当前位置i,然后看当前遍历到的字符是什么,如果遇到的是左括号,什么也不做继续遍历;如果遇到的是数字或者负号,那么我们将连续的数字都找出来,然后转为整型并新建结点,此时我们看 stack 中是否有结点,如果有的话,当前结点就是栈顶结点的子结点,如果栈顶结点没有左子结点,那么此结点就是其左子结点,反之则为其右子结点。之后要将此结点压入栈中。如果我们遍历到的是右括号,说明栈顶元素的子结点已经处理完了,将其移除栈,参见代码如下:

解法二:

class Solution {
public:
TreeNode* str2tree(string s) {
if (s.empty()) return NULL;
stack<TreeNode*> st;
for (int i = ; i < s.size(); ++i) {
int j = i;
if (s[i] == ')') st.pop();
else if ((s[i] >= '' && s[i] <= '') || s[i] == '-') {
while (i + < s.size() && s[i + ] >= '' && s[i + ] <= '') ++i;
TreeNode *cur = new TreeNode(stoi(s.substr(j, i - j + )));
if (!st.empty()) {
TreeNode *t = st.top();
if (!t->left) t->left = cur;
else t->right = cur;
}
st.push(cur);
}
}
return st.top();
}
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/536

类似题目:

Construct String from Binary Tree

参考资料:

https://leetcode.com/problems/construct-binary-tree-from-string/

https://leetcode.com/problems/construct-binary-tree-from-string/discuss/100359/Java-stack-solution

https://leetcode.com/problems/construct-binary-tree-from-string/discuss/100355/Java-Recursive-Solution

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] 536. Construct Binary Tree from String 从字符串创建二叉树的更多相关文章

  1. [LeetCode] Construct Binary Tree from String 从字符串创建二叉树

    You need to construct a binary tree from a string consisting of parenthesis and integers. The whole ...

  2. 【LeetCode】536. Construct Binary Tree from String 解题报告(C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 统计字符串出现的次数 日期 题目地址:https:// ...

  3. 536. Construct Binary Tree from String 从括号字符串中构建二叉树

    [抄题]: You need to construct a binary tree from a string consisting of parenthesis and integers. The ...

  4. (二叉树 递归) leetcode 105. Construct Binary Tree from Preorder and Inorder Traversal

    Given preorder and inorder traversal of a tree, construct the binary tree. Note:You may assume that ...

  5. (二叉树 递归) leetcode 106. Construct Binary Tree from Inorder and Postorder Traversal

    Given inorder and postorder traversal of a tree, construct the binary tree. Note:You may assume that ...

  6. [LeetCode] 106. Construct Binary Tree from Postorder and Inorder Traversal_Medium tag: Tree Traversal

    Given inorder and postorder traversal of a tree, construct the binary tree. Note:You may assume that ...

  7. [LeetCode] 106. Construct Binary Tree from Inorder and Postorder Traversal 由中序和后序遍历建立二叉树

    Given inorder and postorder traversal of a tree, construct the binary tree. Note:You may assume that ...

  8. [Leetcode Week14]Construct Binary Tree from Inorder and Postorder Traversal

    Construct Binary Tree from Inorder and Postorder Traversal 题解 原创文章,拒绝转载 题目来源:https://leetcode.com/pr ...

  9. LeetCode 889. Construct Binary Tree from Preorder and Postorder Traversal

    原题链接在这里:https://leetcode.com/problems/construct-binary-tree-from-preorder-and-postorder-traversal/ 题 ...

随机推荐

  1. C# 中一个限制 Task 并发执行的数量的示例

    直接贴代码了: using System; using System.Linq; using System.Threading; using System.Threading.Tasks; class ...

  2. 『The Counting Problem 数位dp』

    The Counting Problem Description 求 [L,R]内每个数码出现的次数. Input Format 若干行,一行两个正整数 L 和 R. 最后一行 L=R=0,表示输入结 ...

  3. SpringBoot多数据源动态切换数据源

    1.配置多数据源 spring: datasource: master: password: erp_test@abc url: jdbc:mysql://127.0.0.1:3306/M201911 ...

  4. .net Dapper 学习系列(1) ---Dapper入门

    目录 写在前面 为什么选择Dapper 在项目中安装Dapper 在项目中使用Dapper 在项目中使用Dapper 进行单表增删改数据操作 总结 写在前面 Dapper 是一款轻量级ORM架构.为解 ...

  5. Python itertools 操作迭代对象

    Python 的内建模块itertools提供了很多操作迭代对象的方法 参考链接:https://www.liaoxuefeng.com/wiki/1016959663602400/101778314 ...

  6. youtube视频在线下载

    youtube视频在线下载网站: https://www.clipconverter.cc/ youtube视频样例: https://www.youtube.com/watch?v=NMkgz0AR ...

  7. 澄清Fundebug录屏技术的几点误会

    1. "视频"并非真的视频.也不是通过连续播放大量截图来实现 首先请大家观看这个视频: 视频中,当鼠标点击"场景重现",会立即播放一段"视频" ...

  8. [20190505]ts 命令在哪里.txt

    [20190505]ts 命令在哪里.txt --//在论坛问一下ts命令在哪里?没人解答,自己也google看了一下:https://unix.stackexchange.com/questions ...

  9. Java代码实现定时器

    一 import java.util.Timer; import java.util.TimerTask; public class time { public static void main(St ...

  10. odoo10学习笔记十:Actions

    转载请注明原文地址:https://www.cnblogs.com/ygj0930/p/11189319.html actions定义了系统对于用户的操作的响应:登录.按钮.选择项目等. 一:窗口ac ...