找到二叉樹中的最大搜索二叉子樹-Java版

題目

給定一棵二叉樹的頭節點head,已知其中所有節點的值都不一樣,找到含有節點最多的搜索二叉子樹,並返回這棵子樹的頭節點。例如,下圖中,右樹就是左樹的最大搜索子樹。
圖
解題思路—後序遍歷後序遍歷二叉樹,若當前結點的左右子樹都符合搜索二叉樹,就返回當前結點;若有左子樹(右子樹)不符合,則返回右子樹根節點(左子樹根節點)。需要設置全局變量來保存當前子樹的最大值、最小值以及節點數

代碼不是特別好理解,所以給出了main,裏面已經建立了一棵與上圖中一樣的二叉樹,結合debug更易理解。

Java解題—後序遍歷

public static void main(String[] args) {
    // 下面已經建立了一棵與示例圖中相同的二叉樹
    TreeNode root = new TreeNode(6);
    root.left = new TreeNode(1);
    root.right = new TreeNode(12);
    root.left.left = new TreeNode(0);
    root.left.right = new TreeNode(3);
    root.right.left = new TreeNode(10);
    root.right.left.left = new TreeNode(4);
    root.right.left.left.left = new TreeNode(2);
    root.right.left.left.right = new TreeNode(5);
    root.right.left.right = new TreeNode(14);
    root.right.left.right.left = new TreeNode(11);
    root.right.left.right.right = new TreeNode(15);
    root.right.right = new TreeNode(13);
    root.right.right.left = new TreeNode(20);
    root.right.right.right = new TreeNode(16);


    TreeNode sub = biggestSubBST(root);
}


public static TreeNode biggestSubBST(TreeNode head) {
    // 記錄節點數,當前子樹的最大值,最小值
    int[] record = new int[3];
    return posOrder(head, record);
}

public static TreeNode posOrder(TreeNode head, int[] record) {
    if (head == null) {
        // 當遍歷到葉子節點時
        record[0] = 0;
        record[1] = Integer.MAX_VALUE;
        record[2] = Integer.MIN_VALUE;
        return null;
    }
    int value = head.val;// 頭節點的值
    TreeNode left = head.left;// 左子樹的頭節點
    TreeNode right = head.right;// 右子樹的頭節點
    TreeNode lBST = posOrder(left, record);
    int lSize = record[0];
    int lMin = record[1];
    int lMax = record[2];
    TreeNode rBST = posOrder(right, record);
    int rSize = record[0];
    int rMin = record[1];
    int rMax = record[2];
    // 保存當前子樹中的最大值與最小值,不是隻保存左子樹的最大值與右子樹的最小值
    // 因爲在遞歸的過程中,不知道當前是左子樹還是右子樹
    record[1] = Math.min(lMin, value);
    record[2] = Math.max(rMax, value);
    // left == lBST && right == rBST 這個判斷條件特別重要
    // 只有當左右兩個子樹的根節點是當前節點的左右子節點,當前節點才能作爲根節點加入
    if (left == lBST && right == rBST && lMax < value && value < rMin) {
        record[0] = lSize + rSize + 1;
        return head;
    }
    record[0] = Math.max(lSize, rSize);
	// 若左右子樹不能合併,返回當前最長的那個子樹的根節點
    return lSize > rSize ? lBST : rBST;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章