【剑指offer】23.二叉搜索树的后序遍历序列

总目录:

算法之旅导航目录

 

1.问题描述

输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则返回 true ,否则返回 false 。假设输入的数组的任意两个数字都互不相同。
数据范围: 节点数量 0≤n≤1000 ,节点上的值满足 1≤val≤10^5,保证节点上的值各不相同
要求:空间复杂度 O(n),时间时间复杂度 O(n^2)
提示:
1.二叉搜索树是指父亲节点大于左子树中的全部节点,但是小于右子树中的全部节点的树。
2.该题我们约定空树不是二叉搜索树
3.后序遍历是指按照 “左子树-右子树-根节点” 的顺序遍历
4.二叉搜索树不是满树,除根节点外可以任意空缺子节点

 

2.问题分析

 1递归,注意各种边界条件


3.代码实例

递归

 1 class Solution {
 2   public:
 3     bool IsBST(vector<int> sequence) {
 4         int sequenceSize = sequence.size();
 5 
 6         //中止条件
 7         //小于等于一个节点
 8         if (sequenceSize <= 1) {
 9             return true;
10         }
11 
12         //寻找左右子树分割点
13         int rootVal = sequence[sequenceSize - 1];
14         int rightRootId = sequenceSize - 1;//最大到根节点处
15         for (int i = 0; i < sequenceSize; i++) {
16             if (sequence[i] > rootVal) {
17                 rightRootId = i;
18                 break;
19             }
20         }
21         //切割子树
22         vector<int> leftVec, rightVec;
23         for (int i = 0; i < rightRootId; i++) {
24             leftVec.push_back(sequence[i]);
25         }
26         for (int i = rightRootId; i < sequenceSize - 1; i++) {
27             rightVec.push_back(sequence[i]);
28         }
29 
30         //检查根、左右子节点的大小关系
31         int leftSize = leftVec.size();
32         if (leftSize >= 1) {
33             for (int i = 0; i < leftSize; i++) {
34                 if (leftVec[i] >= rootVal) {
35                     return false;
36                 }
37             }
38         }
39         bool isLeftBe = IsBST(leftVec);
40 
41         int rightSize = rightVec.size();
42         if (rightSize >= 1) {
43             for (int i = 0; i < rightSize; i++) {
44                 if (rightVec[i] <= rootVal) {
45                     return false;
46                 }
47             }
48         }
49         bool isRightBe = IsBST(rightVec);
50 
51         //递归调用
52         return  isLeftBe && isRightBe;
53     }
54 
55     bool VerifySquenceOfBST(vector<int> sequence) {
56         int sequenceSize = sequence.size();
57 
58         //中止条件
59         //空树不是搜索树
60         if (sequenceSize <= 0) {
61             return false;
62         }
63 
64         //递归调用
65         return IsBST(sequence);
66     }
67 };
View Code

 优雅的递归,不要那么多vector操作

 1 class Solution {
 2 public:
 3     bool VerifySquenceOfBST(vector<int> sequence) {
 4         int n = sequence.size();
 5         if(n == 0) return false;    // 注意审题, 约定空树不是二叉搜索树
 6         return check(sequence, 0, n - 1);
 7     }
 8 
 9     bool check(vector<int>& sequence, int l, int r){
10         if(l >= r) return true;    // 若当前子树只有一个节点
11 
12         int root = sequence[r];    // 当前子树的根节点
13 
14         // 划分出右子树
15         int j = r - 1;
16         while(j >= 0 && sequence[j] > root) j--;
17 
18         // 检查左子树是不是存在大于根节点的数
19         for(int i = l; i <= j; i++){
20             if(sequence[i] > root) return false;
21         }
22 
23         // 分治法检查左子树和右子树
24         return check(sequence, l, j) && check(sequence, j + 1, r - 1);
25     }
26 };
View Code

 

posted @ 2022-11-12 20:09  啊原来是这样呀  阅读(26)  评论(0)    收藏  举报