leecode刷題-20200528-easy-110.平衡二叉樹

聲明:
作者不是什麼大佬,只是想寫寫算法,提高一下自己的內功。所以代碼可能會非常凌亂,(大佬們就當個笑話看就可以了),但我會認真註釋。


最後如果有路過的大佬,希望可以留下你們的建議和看法,謝謝!

110.平衡二叉樹

一、原題鏈接

110.平衡二叉樹

二、題目介紹

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

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

三、測試用例

1.示例

給定二叉樹 [3,9,20,null,null,15,7]
在這裏插入圖片描述
輸出: true

2.示例

給定二叉樹 [1,2,2,3,3,null,null,4,4]
在這裏插入圖片描述
輸出: false

四、思路解析

個人認爲這道題考察的是:樹的層次遍歷和數的深度遍歷,畢竟我是通過這種依次判斷的方式進行暴力破解。挺適合遞歸入門或是樹算法的入門的

  • 樹的層次遍歷
    通過使用隊列的特性進行遍歷並保存樹的層次結構,用於接下來自上而下地遍歷每個結點
  • 樹的深度遍歷
    這個深度遍歷的時候要注意,不要被子樹的分支所迷惑,我們的目的是找到當前子樹的最深層次。
    舉例

    在這裏插入圖片描述
    這個是對A進行遍歷:代碼的實現下面有。本算法是通過本邏輯獲取結點左右子樹的深度,進行判斷的。每個結點都要進行

五、代碼

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    /**
     * 用於層次遍歷的隊列
     */
    LinkedQueue linkedQueue = new LinkedQueue();
    QueueElem cur;

    /**
     * 層次遍歷,並將結果保存到隊列裏面
     *
     * @param treeNode
     */
    public void touchNode(TreeNode treeNode) {
        if (cur != null && cur.val == treeNode) {
        } else {
            linkedQueue.put(treeNode);
        }
        if (treeNode.left != null) {
            linkedQueue.put(treeNode.left);
        }
        if (treeNode.right != null) {
            linkedQueue.put(treeNode.right);
        }
        if (cur == null) {
            cur = linkedQueue.head;
        }
        cur = cur.next;

        if (cur != null) {
            touchNode(cur.val);
        } else {
            return;
        }
    }


    /**
     * 獲取當前結點的深度(重點)
     *
     * @param curNode
     * @return
     */
    public int getheigh(TreeNode curNode) {
        // 用於保存左右子樹深度,返回大的
        int ri = 0;
        int le = 0;
        // 如果無左右子樹,返回0
        if (curNode.right == null && curNode.left == null) {
            return 0;
        }
        // 無論左右子樹有哪個都需要進入該數進行遍歷並+1
        // 通過+1的遞歸,可以起到累加的作用
        if (curNode.left != null) {
            le = 1 + getheigh(curNode.left);
        }
        if (curNode.right != null) {
            ri = 1 + getheigh(curNode.right);
        }
        // 算是遍歷完了當前結點的左右子樹返回大的數值
        return ri > le ? ri : le;
    }

    /**
     * 只判斷當前結點的左右子樹的深度情況
     *
     * @param curNode
     * @return
     */
    public boolean judge(TreeNode curNode) {
    	// 如果爲空直接返回true
        if (curNode == null) {
            return true;
        }
        // 獲取左子樹的深度
        int left = curNode.left == null ? 0 : 1+getheigh(curNode.left);
        // 獲取右子樹的深度
        int right = curNode.right == null ? 0 : 1+getheigh(curNode.right);

		// 取差判斷當前結點是否滿足平衡二叉樹
        int cha = right - left;
        System.out.println(curNode.val + "  " + left + "  " + right);
        if (cha <= -2 || cha >= 2) {
            return false;
        }
        return true;
    }

    public boolean isBalanced(TreeNode root) {
    	// 如果爲空直接返回true
        if(root == null){
            return true;
        }
        // 保存此樹的層次遍歷的結果
        this.touchNode(root);
        QueueElem cur = linkedQueue.head;

		// 遍歷隊列,依次判斷當前結點是否滿足平衡二叉樹,不滿足直接返回false
        while (cur != null) {
            if (!judge(cur.val)) {
                return false;
            }
            cur = cur.next;
        }
        return true;
    }
}

// 隊列元素
class QueueElem {
    TreeNode val;
    QueueElem next;
    QueueElem pre;

    public QueueElem(TreeNode val) {
        this.val = val;
    }
}

// 鏈表隊列
class LinkedQueue {
    QueueElem head;
    QueueElem last;

    void put(TreeNode treeNode) {
        // 封裝
        QueueElem queueElem = new QueueElem(treeNode);

        // 添加
        if (head == null) {
            head = queueElem;
            last = queueElem;
        } else {
            queueElem.pre = last;
            last.next = queueElem;
            last = queueElem;
        }

    }

    // 刪除
    TreeNode remove() {
        if (head == null) {
            return null;
        }
        if (head == last) {
            TreeNode temp = head.val;
            head = last = null;
            return temp;
        } else {
            TreeNode temp = head.val;
            head.next.pre = null;
            head = head.next;
            return temp;
        }
    }

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