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;
}
};