版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/LSC_333/article/details/90905990
题目大意
给一个序列,如果这个序列是某个二叉搜索树或者是某个二叉搜索树镜像的前序遍历,就输出这个二叉搜索树或二叉搜索树镜像的后序遍历
二叉搜索树:
- 左子树的所有节点的值均小于根节点的值
- 右子树的所有节点的值均不小于根节点的值
输入
每组包含一个用例,每个用例第一行是一个正整数 ,第二行是 个整数表示所给的序列
输出
对每个例子,如果所给的序列满足题意就先在一行输出YES
,第二行输出后序遍历的序列。如果不满足就输出一行NO
样例输入
7
8 6 5 7 10 8 11
7
8 10 11 8 6 7 5
7
8 6 8 5 10 9 11
样例输出
YES
5 7 6 8 11 10 8
YES
11 8 10 7 5 6 8
NO
解析
由于是二叉搜索树,由其性质可以得到:
- 在前序遍历的序列中,从根节点往后找,找到的第一个比根节点大的数就是右子树的根
- 在前序遍历中,从序列的尾部开始找,找到的第一个比根节点的小的数就是左子树的尾部,且根节点的后一个节点就是左子树的根
所以这题其实可以不用构造二叉树就能得解
但是有几点要注意的地方:
- 判断数组长度的时候必须要用
n
而不能用len()
否则提交结果出错 - 还有就是python的最大递归深度貌似不超过1000,所以要用
sys.setrecursionlimit(10000)
来修改递归深度,否则提交会出现返回非0
# -*- coding: utf-8 -*-
# @Time : 2019/6/5 16:06
# @Author : ValarMorghulis
# @File : 1043.py
import sys
sys.setrecursionlimit(10000)
tree = list()
flag = True
ans = list()
def find(root, tail):
global ans
if root > tail:
return
i, j = root + 1, tail
if flag:
while i <= tail and tree[i] < tree[root]:
i += 1
while j > root and tree[j] >= tree[root]:
j -= 1
else:
while i <= tail and tree[i] >= tree[root]:
i += 1
while j > root and tree[j] < tree[root]:
j -= 1
if i - j != 1:
return
find(root + 1, j)
find(i, tail)
ans.append(tree[root])
def solve():
global tree, flag, ans
n = int(input())
tree = list(map(int, input().split()))
find(0, n - 1)
if len(ans) != n:
flag = False
ans.clear()
find(0, n - 1)
if len(ans) == n:
print("YES")
print(*ans)
else:
print("NO")
if __name__ == "__main__":
solve()