# P1229 遍历问题

## 题目描述

我们都很熟悉二叉树的前序、中序、后序遍历,在数据结构中常提出这样的问题:已知一棵二叉树的前序和中序遍历,求它的后序遍历,相应的,已知一棵二叉树的后序遍历和中序遍历序列你也能求出它的前序遍历。然而给定一棵二叉树的前序和后序遍历,你却不能确定其中序遍历序列,考虑如下图中的几棵二叉树:

所有这些二叉树都有着相同的前序遍历和后序遍历,但中序遍历却不相同。

## 输入格式

共两行,第一行表示该二叉树的前序遍历结果 s_1,第二行表示该二叉树的后序遍历结果 s_2。

保证至少存在一棵二叉树满足给出的信息,s _ 1, s _ 2 中只含小写字母,且在某个字符串中不存在相同的字母。

## 输出格式

输出可能的中序遍历序列的总数,结果不超过 2^{63}-1。

##输入输出样例#1

###输入#1

```
abc                           
cba
```

###输出#1

```
4
```
定义 dfs(preL, preR, postL, postR)返回该区间对应的中序序列数。
根 = pre[preL],在后序中找到根的位置 postRootIdx。
左子树长度 = postRootIdx - postL。
如果左子树长度 == 0(即 pre[preL+1] 不存在或 pre[preL+1] == post[postR-1] 吗?要仔细判断)—— 实际上判断条件:
前序第二个字符 pre[preL+1] 在后序中的位置如果是 postR-1(即后序的倒数第二个),则说明左子树为空或右子树为空?
其实应该是:前序第二个字符在后序中的位置如果是 postR-1,说明该节点只有一个孩子,且这个孩子是左孩子还是右孩子不确定。
此时,总方案数 = dfs(左子树) * dfs(右子树) * 2?
但注意,这里左子树长度是 1(那个孩子),右子树长度 0,所以 dfs(左子树) 是那个孩子的子树的中序方案数,dfs(右子树)=1,所以这一层方案数 = dfs(child) * 2。
如果左子树长度 > 0 且 pre[preL+1] != post[postR-1],则正常划分左右,方案数 = dfs(left) * dfs(right)。
代码如下:
#include <iostream>
#include <string>
#include <vector>
using namespace std;

typedef long long ll;

string pre, post;
vector<int> post_pos(26, -1);

ll solve(int preL, int preR, int postL, int postR) {
    if (preL > preR) return 1; 
    if (preL == preR) return 1;

    int root = pre[preL];

    int leftRoot = pre[preL + 1];
    int idx = post_pos[leftRoot - 'a'];

    int leftLen = idx - postL + 1;

  
    if (leftLen == 0 || pre[preL + 1] == post[postR - 1]) {
        // 此时 preL+1..preR 是唯一的孩子子树
        return solve(preL + 1, preR, postL, postR - 1) * 2;
    } else {
   
        ll leftCount = solve(preL + 1, preL + leftLen, postL, idx);
        ll rightCount = solve(preL + leftLen + 1, preR, idx + 1, postR - 1);
        return leftCount * rightCount;
    }
}

int main() {
    cin >> pre >> post;
    int n = pre.size();
    for (int i = 0; i < n; i++) {
        post_pos[post[i] - 'a'] = i;
    }
    ll ans = solve(0, n - 1, 0, n - 1);
    cout << ans << endl;
    return 0;
}
全部评论

相关推荐

2025-12-05 16:20
门头沟学院 Java
1.消息队列(RabbitMQ)保证消息顺序性&nbsp;如何保证同一订单的消息有序消费?2.单线程消费&nbsp;vs&nbsp;多线程消费(如何提升吞吐量仍保证顺序)?3.分片(Hash到同一队列)是否可行?4.Redis数据结构应用&nbsp;项目中使用了哪些Redis数据结构(如Hash、Set、ZSet)?5.购物车数据存储:Hash&nbsp;vs&nbsp;String(JSON)的选择依据?6.String的不可变性优势场景?7.线程池参数设计&nbsp;微服务场景下(如Tomcat),如何设置线程池参数(核心线程数、最8.大线程数、队列容量、拒绝策略)?9.参考因素:CPU核心数、请求响应时间(200ms)、QPS预估?10.拒绝策略:丢弃最老任务时,客户端收到的HTTP状态码11.MySQL优化(EXPLAIN分析)&nbsp;影响查询性能的关键因素(全表扫描、索引覆盖、索引失效、回表、索引下推)?12.多线程与锁&nbsp;ConcurrentHashMap如何保证线程安全(分段锁/CAS)?13.线程安全的定义:为什么HashMap线程不安全?ConcurrentHashMap如何解决?14.多线程put冲突时(如同时写8和10),最终结果如何?15.JVM/集合&nbsp;无直接提问,但涉及线程池和集合的线程安全实现。16.Redis高可用&nbsp;集群模式(哨兵、分片)?主节点宕机后从节点如何接管(优先级、同步延迟)?17.故障检测机制(哨兵&nbsp;vs&nbsp;分片集群)?18.Linux命令&nbsp;查看CPU占用最高的进程(top)?19.查看端口占用(netstat/ss)?20.日志搜索(grep)?21.中间件22.消息队列对比&nbsp;RabbitMQ&nbsp;vs&nbsp;Kafka的适用场景?算法题:未排序数组中第K大元素
查看20道真题和解析
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务