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] Construct Binary Tree from String 从字符串创建二叉树的更多相关文章

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

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

  2. LeetCode Construct Binary Tree from String

    原题链接在这里:https://leetcode.com/problems/construct-binary-tree-from-string/description/ 题目: You need to ...

  3. LeetCode 536----Construct Binary Tree from String

    536. Construct Binary Tree from String You need to construct a binary tree from a string consisting ...

  4. LeetCode:Construct Binary Tree from Inorder and Postorder Traversal,Construct Binary Tree from Preorder and Inorder Traversal

    LeetCode:Construct Binary Tree from Inorder and Postorder Traversal Given inorder and postorder trav ...

  5. Leetcode, construct binary tree from inorder and post order traversal

    Sept. 13, 2015 Spent more than a few hours to work on the leetcode problem, and my favorite blogs ab ...

  6. [LeetCode] 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 ...

  7. LeetCode: Construct Binary Tree from Inorder and Postorder Traversal 解题报告

    Construct Binary Tree from Inorder and Postorder Traversal Given inorder and postorder traversal of ...

  8. LeetCode: Construct Binary Tree from Preorder and Inorder Traversal 解题报告

    Construct Binary Tree from Preorder and Inorder Traversal Given preorder and inorder traversal of a ...

  9. Leetcode | Construct Binary Tree from Inorder and (Preorder or Postorder) Traversal

    Construct Binary Tree from Preorder and Inorder Traversal Given preorder and inorder traversal of a ...

随机推荐

  1. java排序算法(四):冒泡排序

    java排序算法(四):冒泡排序 冒泡排序是计算机的一种排序方法,它的时间复杂度是o(n^2),虽然不及堆排序.快速排序o(nlogn,底数为2).但是有两个优点 1.编程复杂度很低.很容易写出代码 ...

  2. 开源小工具 酷狗、网易音乐缓存文件转mp3工具

    发布一个开源小工具,支持将酷狗和网易云音乐的缓存文件转码为MP3文件. 以前写过kgtemp文件转mp3工具,正好当前又有网易云音乐缓存文件需求,因此就在原来小工具的基础上做了一点修改,增加了对网易云 ...

  3. ES5和ES6两个值的比较

    ES5比较两个值是否相等 1)相等运算符 (==):比较两个数值是否相等,自动转换类型后再进行比较 2)全等运算符(===):比较两个比较值的数值和类型是否相等 ES5的特殊: ES6提出" ...

  4. 听翁恺老师mooc笔记(3)--指针的定义

    在上一个blog学习了&运算符,使用&取了变量.数组等地址,有什么用那?如果能够将取得的变量的地址传递给函数,能否通过这个地址在函数内访问到外部这个变量?答案是肯定的,scanf(&q ...

  5. MySort实验报告

    实验日期:2017.5.2 实验内容:利用sort方法对已给的数据进行重新排序. 实验原图: 对原代码进行添加,补充新的内容: 在for循环中,新输入一个变量j,并新定义新的长度toSort.leng ...

  6. AWS EMR上搭建HBase环境

    0. 概述 AWS的EMR服务为客户提供的托管 Hadoop 框架可以让您轻松.快 速.经济高效地在多个动态可扩展的 Amazon EC2 实例之间分发和处理 大量数据.您还可以运行其他常用的分发框架 ...

  7. 微信支付 chooseWXPay:fail

    本来以为解决了微信支付get_brand_wcpay_request:faill这个问题后就万事大吉了,结果又迈入了另一个坑... 问题原因: 1.生成签名的时间戳参数名timestamp的s大小写问 ...

  8. PM2使用心得

    PM2是node进程管理工具,可以利用它来简化很多node应用管理的繁琐任务,如性能监控.自动重启.负载均衡等,而且使用非常简单. 安装 npm install -g pm2 常用命令 $ npm i ...

  9. 让linux远程主机在后台运行脚本

    后台挂起:python xxx.py & 在脚本命令后面加入"&"符号就可以后台运行.结束进程:kill -9 sidps -ef | grep ... 查询sid

  10. WPF自定义控件与样式-自定义按钮(Button)

    一.前言 程序界面上的按钮多种多样,常用的就这几种:普通按钮.图标按钮.文字按钮.图片文字混合按钮.本文章记录了不同样式类型的按钮实现方法. 二.固定样式的按钮 固定样式的按钮一般在临时使用时或程序的 ...