536. 从字符串生成二叉树

Q:

在这里插入图片描述

A:

1.递归,左右边界做函数参数,太弟弟略过。
2.迭代,鼓捣了半天
题目给的字符串只看数字顺序的话是前序。那么想一下我们写非递归前序遍历时候,对于一个节点cur,如果不是空直接输出它的值,然后放到栈顶,再令cur=cur的左孩子进行循环。如果cur为空,那么令cur=栈顶的右孩子并pop栈顶并继续。

对于给定前序字符串,假如前三个数字是a、b、c,首先应该新建一个值为a的节点A(毕竟我们迭代只能从前向后不是?)。那么接下来对照非递归遍历,这时候我们应该输出它的值a再放到栈顶,再取其左节点,但我们这里是要用字符串建树。所以我们不用输出它的值,放到栈顶这一步是一样的。而由于字符串是前序,a后面紧接着的b就是a的左孩子,所以继续遍历数字b就好了。对于数字b我们建立节点B,这时栈顶就是B的父亲,所以我们把B和栈顶(也就是A)连起来,当然我们要查看一下栈顶(A)有无左孩子,没左孩子那么我们就把A的左孩子置为B,如果有左孩子了那么把A的右孩子置为B(因为之后遍历c的时候建立节点C还要和A相连,必须得判断一下)。

比较重要的一个地方:假设当前数字为x,这个数字x马上要新建节点X,栈顶始终存的是X的父亲。因为字符串给的顺序是根-》左-》右,我们有理由认为,最先考察的跟一定先新建了节点并放在了栈顶,那么接下来的左孩子入栈后。出栈左孩子,(此时栈顶是左孩子的父亲),把左孩子和它爸连起来。之后右孩子再入栈。再出栈右孩子,栈顶还是父亲节点没有动,再把右孩子和父节点连起来。这时候,根节点为根的二叉树全部重构好了,此时根节点下面的节点就都隐藏了,它可以作为一个单独的节点,可能还有另一个节点P是它的父亲,但P是看不到之前根节点的孩子的,因为此时栈中只有之前的根节点,它的孩子们、孩子的孩子们都pop掉了。说的比较啰嗦,感觉我真不太适合当老师。。
2019年11月11日 20:04:41

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* str2tree(string s) {
        s+=')';
        int len=s.size();
        if(len==1){return 0;}
        int flag=1,temp=0;
        stack<TreeNode*> sta;
        TreeNode* root=new TreeNode(0);
        sta.push(root);
        TreeNode* cur=0,*par=0;
        for(int i=0;i<len;++i){
            if(s[i]=='('){
                ;
            }
            else if(s[i]==')'){
                cur=sta.top();
                sta.pop();
                par=sta.top();
                if(par->left){
                   par->right=cur;
                }
                else{
                    par->left=cur;
                }
            }
            else if(s[i]=='-'){
                flag=-1;
            }
            else{   //s[i]为数字
                temp=temp*10+(s[i]-'0');
                if(s[i+1]==')' or s[i+1]=='('){
                    cur=new TreeNode(temp*flag);
                    sta.push(cur);
                    flag=1,temp=0;
                }
            }
        }
        return root->left;
    }
};
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值