1. 題目
- 給定一個二叉樹,判斷其是否是一個有效的二叉搜索樹:https://leetcode-cn.com/problems/validate-binary-search-tree/
- 給定一個二叉樹, 找到該樹中兩個指定節點的最近公共祖先:https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/
2. 基本知識
樹、二叉樹、二叉搜索樹
2.1 樹
由N個點構成的一種數據結構,有一個根節點和多層的子節點組成,連接的順序都是從根節點指向孩子節點。每一個子節點都只有一個前驅節點,但一個父節點可能有多個孩子節點。
2.2 二叉樹
二叉樹是樹的一種,它的特點是每一個節點最多隻有兩個子節點。
2.3 二叉搜索樹
它是二叉樹的一種,又叫有序二叉樹。它是指一棵空樹或者有以下性質的二叉樹。增刪查的時機複雜度爲O(logn)
- 左子樹上所有節點的值均小於它的根節點的值
- 右子樹上所有的節點的值均大於它的根節點的值
- 左右子樹也分別爲小二叉搜索樹
3. 算法題解題
3.1 給定一個二叉樹,判斷其是否是一個有效的二叉搜索樹
假設存在鏈表 1 → 2 → 3 → Ø,我們想要把它改成 Ø ← 1 ← 2 ← 3。把每個節點的next指向它的前一個節點即可。
解法1:中序遍歷法
左節點-父節點-右節點,這個遍歷順序,則判斷前一個節點的值比後一個節點的值小即可。
時間複雜度爲O(n),空間複雜度也爲O(n)
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}
public boolean isValidBST(TreeNode root) {
Stack<TreeNode> stack = new Stack<TreeNode>();
if (root == null) {
return true;
}
double inorder = -Double.MAX_VALUE;
while (!stack.isEmpty() || root != null) {
while(root != null){
stack.push(root);
root = root.left;
}
root = stack.pop();
if (root.val < inorder) {
return false;
}
inorder = root.val;
root = root.right;
}
return false;
}
解法2: 遞歸
分別遞歸左右子樹,一直遞歸找到左子樹的最大值,右子樹的最小值,然後把返回的值進行比較,左節點最大值小於根節點,小於右節點最小值。
public boolean isValidBST(TreeNode root) {
return validHelper(root ,null, null);
}
public boolean validHelper(TreeNode root, Integer min, Integer max){
if (root == null) {
return true;
}
Integer tempVal = root.val;
// 當前值和最小值比較
if (min != null && tempVal <= min) return false;
// 當前值和最大值比較
if (max != null && tempVal >= max) return false;
//遞歸循環
//左子樹,最大值是當前節點值
if (!validHelper(root.left, min, tempVal)) return false;
//右子樹,最小值是當前節點值
if(!validHelper(root.right, tempVal, max)) return false;
return true;
}
3.2 給定一個二叉樹, 找到該樹中兩個指定節點的最近公共祖先
tips:自己也可以是自己的祖先節點
解法1: 遞歸法
從根節點開始遍歷,如果找到其中一個節點,則 temp 標記爲1,如果找到其中一個則認爲該分支找到了。繼續遍歷另一個分支,直到left、right、temp其中兩個爲1時,則認爲找到了公共祖先。
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
recurseTree(root, p, q);
return result;
}
TreeNode result;
private boolean recurseTree(TreeNode currentNode, TreeNode p, TreeNode q) {
if (currentNode == null) {
return false;
}
int left = recurseTree(currentNode.left, p, q) ? 1 : 0;
int right = recurseTree(currentNode.right, p, q) ? 1 : 0;
int temp= 0;
if (currentNode == p || currentNode == q) {
temp = 1;
}
if (temp + left + right == 2) {
result = currentNode;
}
if (temp + left + right > 0) {
return true;
}
return false;
}
4. Tips
一個可以免費上傳圖片,並分享鏈接的網站
https://sm.ms/
點擊,並上傳照片。
然後,分享鏈接即可。