二叉搜索树实战秘籍:掌握经典解法,上分无忧
2023-02-26 17:40:51
二叉搜索树(BST):掌握经典解法,轻松应聘 LeetCode
概述
二叉搜索树(BST)是一种重要的数据结构,在计算机科学中有着广泛的应用。BST 的特点是,每个节点的值都比其左子节点的值大,而比其右子节点的值小。这种结构使得 BST 非常适合用于查找和插入操作,时间复杂度为 O(logn)。
在 LeetCode 面试题中,BST 经常出现。掌握 BST 的经典解法可以帮助你轻松上分。本文将分享 5 个经典问题及其解决方案,包括:
1. 判断 BST 的合法性
2. 计算 BST 中某个范围内的元素和
3. 根据前序遍历结果重建 BST
4. 寻找 BST 中两个节点的最近公共祖先
5. 实现 BST 的插入、删除和查找操作
1. 判断 BST 的合法性
给定一个二叉树,判断它是否是一个 BST。
Java 代码示例:
public boolean isValidBST(TreeNode root) {
return isValidBST(root, Long.MIN_VALUE, Long.MAX_VALUE);
}
private boolean isValidBST(TreeNode root, long minVal, long maxVal) {
if (root == null) {
return true;
}
if (root.val <= minVal || root.val >= maxVal) {
return false;
}
return isValidBST(root.left, minVal, root.val) && isValidBST(root.right, root.val, maxVal);
}
2. 计算 BST 中某个范围内的元素和
给定一个 BST,计算 BST 中某个范围内的元素和。
Java 代码示例:
public int rangeSumBST(TreeNode root, int low, int high) {
if (root == null) {
return 0;
}
int sum = 0;
if (root.val >= low && root.val <= high) {
sum += root.val;
}
if (root.val > low) {
sum += rangeSumBST(root.left, low, high);
}
if (root.val < high) {
sum += rangeSumBST(root.right, low, high);
}
return sum;
}
3. 根据前序遍历结果重建 BST
给定一个前序遍历的结果,重建 BST。
Java 代码示例:
public TreeNode buildTree(int[] preorder) {
if (preorder == null || preorder.length == 0) {
return null;
}
int rootVal = preorder[0];
TreeNode root = new TreeNode(rootVal);
int leftEndIndex = 0;
for (int i = 1; i < preorder.length; i++) {
if (preorder[i] > rootVal) {
leftEndIndex = i;
break;
}
}
int[] leftSubtree = Arrays.copyOfRange(preorder, 1, leftEndIndex);
int[] rightSubtree = Arrays.copyOfRange(preorder, leftEndIndex, preorder.length);
root.left = buildTree(leftSubtree);
root.right = buildTree(rightSubtree);
return root;
}
4. 寻找 BST 中两个节点的最近公共祖先
给定 BST 中两个节点,找到它们的最近公共祖先(LCA)。
Java 代码示例:
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null || root == p || root == q) {
return root;
}
TreeNode leftLCA = lowestCommonAncestor(root.left, p, q);
TreeNode rightLCA = lowestCommonAncestor(root.right, p, q);
if (leftLCA != null && rightLCA != null) {
return root;
}
return leftLCA != null ? leftLCA : rightLCA;
}
5. 实现 BST 的插入、删除和查找操作
Java 代码示例:
public void insert(int val) {
TreeNode newNode = new TreeNode(val);
if (root == null) {
root = newNode;
return;
}
TreeNode curr = root;
while (true) {
if (val < curr.val) {
if (curr.left == null) {
curr.left = newNode;
return;
} else {
curr = curr.left;
}
} else {
if (curr.right == null) {
curr.right = newNode;
return;
} else {
curr = curr.right;
}
}
}
}
public void delete(int val) {
TreeNode curr = root;
TreeNode parent = null;
while (curr != null && curr.val != val) {
parent = curr;
if (val < curr.val) {
curr = curr.left;
} else {
curr = curr.right;
}
}
if (curr == null) {
return;
}
if (curr.left == null && curr.right == null) {
if (parent == null) {
root = null;
} else {
if (parent.left == curr) {
parent.left = null;
} else {
parent.right = null;
}
}
} else if (curr.left != null && curr.right == null) {
if (parent == null) {
root = curr.left;
} else {
if (parent.left == curr) {
parent.left = curr.left;
} else {
parent.right = curr.left;
}
}
} else if (curr.left == null && curr.right != null) {
if (parent == null) {
root = curr.right;
} else {
if (parent.left == curr) {
parent.left = curr.right;
} else {
parent.right = curr.right;
}
}
} else {
TreeNode successor = curr.right;
TreeNode successorParent = curr;
while (successor.left != null) {
successorParent = successor;
successor = successor.left;
}
curr.val = successor.val;
if (successorParent.left == successor) {
successorParent.left = successor.right;
} else {
successorParent.right = successor.right;
}
}
}
public TreeNode search(int val) {
TreeNode curr = root;
while (curr != null && curr.val != val) {
if (val < curr.val) {
curr = curr.left;
} else {
curr = curr.right;
}
}
return curr;
}
常见问题解答
1. 什么是二叉搜索树?
二叉搜索树(BST)是一种数据结构,其中每个节点的值都比其左子节点的值大,而比其右子节点的值小。
2. BST 的优点有哪些?
BST 的优点包括快速查找和插入操作,时间复杂度为 O(logn)。
3. BST 在 LeetCode 面试题中有哪些应用?
BST 在 LeetCode 面试题中经常被用来解决各种问题,例如判断 BST 的合法性、计算 BST 中某个范围内的元素和、根据前序遍历结果重建 BST,以及查找 BST 中两个节点的最近公共祖先。
4. 如何判断一个二叉树是否是一个 BST?
可以使用递归方法判断一个二叉树是否是一个 BST。首先,检查根节点是否满足 BST 的性质。然后,递归地检查左子树和右子树是否也是 BST。
5. 如何在 BST 中查找一个节点?
可以在 BST 中使用递归方法查找一个节点。从根节点开始,如果要查找的值等于根节点的值,则返回根节点。如果要查找的值小于根节点的值,则递归地搜索左子树。否则,递归地搜索右子树。