[LeetCode](面試題33)二叉搜索樹的後序遍歷序列

題目

輸入一個整數數組,判斷該數組是不是某二叉搜索樹的後序遍歷結果。如果是則返回 true,否則返回 false。假設輸入的數組的任意兩個數字都互不相同。

參考以下這顆二叉搜索樹:

     5
    / \
   2   6
  / \
 1   3

示例 1:

輸入: [1,6,3,2,5]
輸出: false

示例 2:

輸入: [1,3,2,6,5]
輸出: true

提示:

  1. 數組長度 <= 1000

解題思路

二叉搜索樹的左子樹節點的值小於根節點,二叉搜索樹的右子樹節點的值大於根節點。所以可以根據二叉搜索樹的定義,通過遞歸,判斷所有子樹的正確性 (即其後序遍歷是否滿足二叉搜索樹的定義)。若所有子樹都正確,則此序列爲二叉搜索樹的後序遍歷。

算法步驟:

  • 1)遞歸終止條件: 當 left>=right ,說明此子樹節點數量 ≤,無需判別正確性,因此直接返回 true;
  • 2)找根節點,根節點爲序列的最後一個元素:root = postorder[right];
  • 3)劃分出左右子樹:遍歷後序遍歷的 [left, right-1] 區間,尋找第一個大於根節點的位置,索引記爲 i 。此時,可劃分出左子樹區間 [left, i-1], 右子樹區間 [i, right-1],根節點索引 right。
  • 4)判斷左右子樹是否爲二叉搜索樹:
    • 4.1)左子樹區間 [left, i-1] 內的所有節點都應小於 postorder[right],而上一步劃分左右子樹時已經保證左子樹區間的正確性,因此只需要判斷右子樹區間即可。
    • 4.2)右子樹區間 [i, right-1] 內的所有節點都應大於 postorder[right],逐個遍歷此區間,當遇到小於 postorder[right] 的節點則跳出,直接返回 false。
  • 5)返回值:所有子樹都需正確纔可判定正確,因此使用“與邏輯符 &&” 連接。

代碼

class Solution {
    public boolean verifyPostorder(int[] postorder) {
        return isPoster(postorder, 0, postorder.length-1);
    }

    private boolean isPoster(int[] postorder, int left, int right){
        if(left>=right){
            return true;
        }
        // 根節點是數組的最後一個
        int root = postorder[right];
        // 二叉搜索樹的左子樹節點的值應該小於根節點
        int i=left;
        for(; i<right; i++){
            if(postorder[i] > root){
                break;
            }
        }
        // 二叉搜索樹的右子樹節點的值應該大於根節點
        int j = i;
        for(; j<right; j++){
            // 如果在右子樹出現小於根節點的值,直接返回false
            if(postorder[j] < root){
                return false;
            }
        }
        // 判斷左子樹是否是二叉搜索樹
        boolean isLeft = isPoster(postorder, left, i-1);
        // 判斷右子樹是否是二叉搜索樹
        boolean isRight = isPoster(postorder, i, right-1);
        
        return isLeft && isRight;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章