(Java)leetcode-110 Balanced Binary Tree(平衡二叉樹)

給定一個二叉樹,判斷它是否是高度平衡的二叉樹。

本題中,一棵高度平衡二叉樹定義爲:
一個二叉樹每個節點 的左右兩個子樹的高度差的絕對值不超過1。

在這裏插入圖片描述
通常認爲此問題有兩種解決方案:自上而下 / 自下而上的方法。

思路1:自上而下

第一種方法嚴格按照平衡二叉樹的定義檢查樹是否平衡:兩個子樹的高度之差不大於1,並且左子樹和右子樹也都平衡。使用輔助函數 calDepth(),我們可以輕鬆地編寫代碼:

代碼

class Solution {
    public boolean isBalanced(TreeNode root) {
        if (root == null) return true;
        return (Math.abs(calDepth(root.left) - calDepth(root.right)) <= 1) && isBalanced(root.left) && isBalanced(root.right);
    }

	private int calDepth(TreeNode root) {
		if (root == null) return 0;
		return Math.max(calDepth(root.left), calDepth(root.right)) + 1;
	}
}

對於當前節點根,實際上調用其左側和右側子節點的calDepth()實際上必須訪問其所有子節點,因此複雜度爲O(N)。我們對樹中的每個節點執行此操作,因此isBalanced的總體複雜度將爲 O(N ^ 2)
在這裏插入圖片描述

思路2:自下而上

第二種方法基於DFS。而不是爲每個子節點顯式調用 calDepth(),而是在DFS遞歸中返回當前節點的高度。.
噹噹前節點(含)的子樹平衡時,函數dfsHeight()返回一個非負值作爲高度。否則返回-1。
根據兩個子節點的leftHeight和rightHeight,父節點可以檢查子樹是否平衡,並確定其返回值。

在這種自下而上的方法中,樹中的每個節點僅需要訪問一次,因爲每個節點的高度已經被記錄並返回給遞歸的上一層,上層節點求高度時直接用,而不是如方法1每個節點都得往下求一次高度。

因此,時間複雜度爲O(N),優於第一種解決方案。

代碼

class Solution {
    public boolean isBalanced(TreeNode root) {
        return dfsHeight (root) != -1;
    }

    private int dfsHeight (TreeNode root) {
        if (root == null) return 0;
        
        // 求左子樹高度
        int leftHeight = dfsHeight (root.left);
        if (leftHeight == -1) return -1;

        // 求右子樹高度
        int rightHeight = dfsHeight (root.right);
        if (rightHeight == -1) return -1;
        
        // 判斷當前節點爲根的樹,是否不平衡
        if (Math.abs(leftHeight - rightHeight) > 1)  return -1;
        
        // 返回當前樹的高度
        return Math.max (leftHeight, rightHeight) + 1;
    }
}

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章