题意
输入是一个 有点特别的 一个二叉树的后序遍历的字符串;
其中 字符串中的小写字母为叶子节点, 大写字母为非叶子节点;
然后输出这颗树的 中序遍历;
input
2
bcA
efBghCA
output
bAc
eBfAgCh
思路
当时做的时候,没有注意一句话:
Given the post-order traversal of a binary tree, each of whose non-leaf nodes has exactly two children
这句话说明是完全二叉树。。。结果纠结了很长时间
做了一些二叉树的题目, 一般思路就是:找到根,找到左子树,找到右子树, 然后递归左子树,递归右子树。
这个也可以这样考虑:
将当前树分为三部分: left root right
后序遍历的最后一个字符肯定是 root 部分。
然后由于是 完全二叉树: 每一个非叶子节点必有俩孩子,则一棵树中,左右子树中,大写字母要比小写字母少一个;这里可以拆分出左右子树。
有一点需要注意的是: 需要倒着搜索,因为完全二叉树的左子树中嵌套的子树也满足条件,因此需要先找出右子树部分。
代码
/*Accepted 2801 C++ 0.5K 0'00.02" 1352K */
#include <iostream>
#include <string>
using namespace std;
int T;
string s;
string in_order(string s)
{
int len=s.length(),n=0,i;
if (len==1)return s;//只有一个字符 直接返回
for(i=len-2;i>=0;i--)
{//从后向前 即:先找右子树
if(s[i]>='a'&&s[i]<='z')n++;
else n--;
if(n==1) break;
}
return in_order(s.substr(0,i))+s.substr(len-1,1)+in_order(s.substr(i,len-i-1));
}
int main()
{
cin>>T;
while(T--)
{
cin>>s;
cout<<in_order(s)<<endl;
}
}
另附建立完整的树之后 在输出中序的代码,核心相同
/*Accepted 2801 C++ 1.1K 0'00.01" 1616K */
#include <iostream>
using namespace std;
struct TreeNode{
TreeNode *left;
TreeNode *right;
char ch;
};
TreeNode * createTree(TreeNode *root,string s)
{//建树
int len=s.length(),i=0,n=0;
root=new TreeNode();
root->ch=s[len-1];
root->left=root->right=NULL;
if(len==1) return root;//叶节点
for(i=len-2;i>=0;i--)
{
if(s[i]>='a'&&s[i]<='z') n++;
else n--;
if(n==1) break;
}
root->left=createTree(root->left,s.substr(0,i));
root->right=createTree(root->right,s.substr(i,len-i-1));
return root;
}
void inOrder(TreeNode *root)
{//中序遍历
if(!root) return;
inOrder(root->left);
cout<<root->ch;
inOrder(root->right);
}
void del(TreeNode *root)
{
if(!root) return;
if(!root->left&&!root->right)
{
delete(root);
return;
}
del(root->left);
del(root->right);
}
int main()
{
int T;
string s;
cin>>T;
while(T--)
{
cin>>s;
TreeNode *root;
root=createTree(root,s);
inOrder(root);
cout<<'\n';
del(root);
}
}