聲明:
作者不是什麼大佬,只是想寫寫算法,提高一下自己的內功。所以代碼可能會非常凌亂,(大佬們就當個笑話看就可以了),但我會認真註釋。
最後如果有路過的大佬,希望可以留下你們的建議和看法,謝謝!
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;
}
}
}