剑指Offer - 九度1367 - 二叉搜索树的后序遍历序列
生活随笔
收集整理的這篇文章主要介紹了
剑指Offer - 九度1367 - 二叉搜索树的后序遍历序列
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
劍指Offer - 九度1367 - 二叉搜索樹的后序遍歷序列
2013-11-23 03:16 題目描述: 輸入: 輸出: 樣例輸入: 7
5 7 6 9 11 10 8
4
7 4 6 5
樣例輸出: Yes
No 題意分析:
題目要求給定一個數組,判斷此數組能不能是一顆BST的后序遍歷。對于后序遍歷,最后一個元素對應根節點,前一段元素小于根節點,后一段元素大于根節點。
對于數組a[n],如果存在1<=k<=n,使得a[1]~a[k - 1]均小于a[n],a[k]~a[n - 1]均大于a[n],則可以劃分出兩個子樹,兩個子樹可以為空。
按照這種劃分標準遞歸往下檢查所有子樹,全部符合的話,說明能夠造出一個二叉搜索樹。否則不符合二叉搜索樹的結構。
所有節點遍歷一次,有O(n)時間開銷,但因為找出劃分左右子樹的節點a[k]需要O(n)的開銷,所以實際是O(nlog n),推導如下:
T(n) = 2 * T(n / 2) + O(1) + O(n)
T(n) = 2 * T(n / 2) + O(n)
T(n) = 4 * T(n / 4) + 2 * (O(n / 2)) + O(n)
T(n) = 4 * T(n / 4) + 2 * O(n)
T(n) = 2 ^ log(n) * T(1) + log(n) * O(n)
T(n) = O(n) + O(n * log(n))
T(n) = O(n * log(n))
空間復雜度O(1),不需要額外數組。 1 // 652939 zhuli19901106 1367 Accepted 點擊此處查看所有case的執行結果 1020KB 1192B 10MS 2 // 201311172259 3 #include <cstdio> 4 using namespace std; 5 6 bool check_postorder(const int a[], int left, int right) 7 { 8 if(a == NULL || left < 0 || right < 0 || left > right){ 9 return false; 10 } 11 12 if(left == right){ 13 return true; 14 } 15 16 int i; 17 18 i = left; 19 while(i <= right - 1 && a[i] < a[right]){ 20 ++i; 21 } 22 if(i == right){ 23 // right substree is empty 24 return check_postorder(a, left, right - 1); 25 }else if(i == left){ 26 // left substree is empty 27 for(; i <= right - 1; ++i){ 28 if(a[i] < a[right]){ 29 return false; 30 } 31 } 32 return check_postorder(a, left, right - 1); 33 }else{ 34 int pos = i; 35 for(; i <= right - 1; ++i){ 36 if(a[i] < a[right]){ 37 return false; 38 } 39 } 40 return check_postorder(a, left, pos - 1) && check_postorder(a, pos, right - 1); 41 } 42 } 43 44 int main() 45 { 46 const int MAXN = 10005; 47 int a[MAXN]; 48 int n, i; 49 50 while(scanf("%d", &n) == 1){ 51 for(i = 0; i < n; ++i){ 52 scanf("%d", &a[i]); 53 } 54 if(check_postorder(a, 0, n - 1)){ 55 printf("Yes\n"); 56 }else{ 57 printf("No\n"); 58 } 59 } 60 61 return 0; 62 }
2013-11-23 03:16 題目描述:
輸入一個整數數組,判斷該數組是不是某二叉搜索樹的后序遍歷的結果。如果是則輸出Yes,否則輸出No。假設輸入的數組的任意兩個數字都互不相同。
每個測試案例包括2行:
第一行為1個整數n(1<=n<=10000),表示數組的長度。
第二行包含n個整數,表示這個數組,數組中的數的范圍是[0,100000000]。
對應每個測試案例,如果輸入數組是某二叉搜索樹的后序遍歷的結果輸出Yes,否則輸出No。
題目要求給定一個數組,判斷此數組能不能是一顆BST的后序遍歷。對于后序遍歷,最后一個元素對應根節點,前一段元素小于根節點,后一段元素大于根節點。
對于數組a[n],如果存在1<=k<=n,使得a[1]~a[k - 1]均小于a[n],a[k]~a[n - 1]均大于a[n],則可以劃分出兩個子樹,兩個子樹可以為空。
按照這種劃分標準遞歸往下檢查所有子樹,全部符合的話,說明能夠造出一個二叉搜索樹。否則不符合二叉搜索樹的結構。
所有節點遍歷一次,有O(n)時間開銷,但因為找出劃分左右子樹的節點a[k]需要O(n)的開銷,所以實際是O(nlog n),推導如下:
T(n) = 2 * T(n / 2) + O(1) + O(n)
T(n) = 2 * T(n / 2) + O(n)
T(n) = 4 * T(n / 4) + 2 * (O(n / 2)) + O(n)
T(n) = 4 * T(n / 4) + 2 * O(n)
T(n) = 2 ^ log(n) * T(1) + log(n) * O(n)
T(n) = O(n) + O(n * log(n))
T(n) = O(n * log(n))
空間復雜度O(1),不需要額外數組。 1 // 652939 zhuli19901106 1367 Accepted 點擊此處查看所有case的執行結果 1020KB 1192B 10MS 2 // 201311172259 3 #include <cstdio> 4 using namespace std; 5 6 bool check_postorder(const int a[], int left, int right) 7 { 8 if(a == NULL || left < 0 || right < 0 || left > right){ 9 return false; 10 } 11 12 if(left == right){ 13 return true; 14 } 15 16 int i; 17 18 i = left; 19 while(i <= right - 1 && a[i] < a[right]){ 20 ++i; 21 } 22 if(i == right){ 23 // right substree is empty 24 return check_postorder(a, left, right - 1); 25 }else if(i == left){ 26 // left substree is empty 27 for(; i <= right - 1; ++i){ 28 if(a[i] < a[right]){ 29 return false; 30 } 31 } 32 return check_postorder(a, left, right - 1); 33 }else{ 34 int pos = i; 35 for(; i <= right - 1; ++i){ 36 if(a[i] < a[right]){ 37 return false; 38 } 39 } 40 return check_postorder(a, left, pos - 1) && check_postorder(a, pos, right - 1); 41 } 42 } 43 44 int main() 45 { 46 const int MAXN = 10005; 47 int a[MAXN]; 48 int n, i; 49 50 while(scanf("%d", &n) == 1){ 51 for(i = 0; i < n; ++i){ 52 scanf("%d", &a[i]); 53 } 54 if(check_postorder(a, 0, n - 1)){ 55 printf("Yes\n"); 56 }else{ 57 printf("No\n"); 58 } 59 } 60 61 return 0; 62 }
?
轉載于:https://www.cnblogs.com/zhuli19901106/p/3438577.html
總結
以上是生活随笔為你收集整理的剑指Offer - 九度1367 - 二叉搜索树的后序遍历序列的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 招行Hello Kitty卡功能介绍:透
- 下一篇: 被叫“红衣大炮” 周鸿祎回应:现在努力自