第三部分、二叉搜索树相关
二叉搜索树最大的性质:中序遍历是递增的
1. 验证二叉搜索树
class Solution {
public boolean isValidBST(TreeNode root) {
if(root == null) return true;
return dfs(root , Long.MIN_VALUE , Long.MAX_VALUE);
}
boolean dfs(TreeNode root , long min , long max){
if(root == null) return true;
//如果root的值比最小值还小或者比最大值还大,说明不是BST
if(root.val <= min || root.val >= max) return false;
return dfs(root.left , min , root.val) && dfs(root.right , root.val , max);
}
}
2. 二叉搜索树的第k大节点
class Solution {
TreeNode cur = null;
int count = 0;
int res = 0;
public int kthLargest(TreeNode root, int k) {
if(root == null) return 0;
dfs(root , k);
return res;
}
void dfs(TreeNode root , int k){
if(root == null) return;
dfs(root.right , k); //注意中序遍历反过来
cur = root;
count++; //记录是否到第k个了,如果到了就计入res返回
if(count == k){
res = root.val;
return;
}
dfs(root.left , k);
}
}
3. 二叉搜索树的最小绝对差
class Solution {
TreeNode pre = null;
int res = Integer.MAX_VALUE;
public int getMinimumDifference(TreeNode root) {
if(root == null) return 0;
dfs(root);
return res;
}
void dfs(TreeNode root){
if(root == null) return;
dfs(root.left);
if(pre != null) res = Math.min(res , root.val - pre.val);
pre = root;
dfs(root.right);
}
}
4. 删除二叉搜索树中的节点
class Solution {
public TreeNode deleteNode(TreeNode root, int key) {
if(root == null) return null;
if(root.val < key) root.right = deleteNode(root.right , key);
else if(root.val > key) root.left = deleteNode(root.left , key);
else{
//找到节点了
//1.左右子树有一个为空,返回另外一个子树作为根节点
if (root.left == null) return root.right;
else if (root.right == null) return root.left;
else{
// 左右子树都存在,返回后继节点(右子树最左叶子)作为新的根
// 把原来的左子树 接到中继节点的左子树上
TreeNode cur = root.right;
while (cur.left != null) cur = cur.left;
cur.left = root.left;
return root.right;
}
}
return root;
}
}
5. 插入二叉搜索树中的节点
class Solution {
public TreeNode insertIntoBST(TreeNode root, int val) {
if(root == null) return new TreeNode(val);
TreeNode p = root , cur = root;
while(cur != null){ // cur往下找,p记住原来的位置
p = cur;
cur = cur.val > val ? cur.left : cur.right;
}
if(p.val < val) p.right = new TreeNode(val);
else p.left = new TreeNode(val);
return root;
}
}
6. 搜索二叉搜索树中的节点
class Solution {
public TreeNode searchBST(TreeNode root, int val) {
if(root == null) return null;
if(root.val > val) return searchBST(root.left , val);
else if(root.val < val) return searchBST(root.right, val);
else return root;
}
}
7. 验证是否是二叉搜索树的后序遍历
class Solution {
//左右中
public boolean verifyPostorder(int[] postorder) {
return dfs(postorder , 0 , postorder.length-1);
}
boolean dfs(int[] postorder , int l , int r){
if(l >= r) return true;
int index = l;
while(postorder[index] < postorder[r]) index++;
int mid = index;
while(postorder[index] > postorder[r]) index++;
if(index != r ) return false;
return dfs(postorder , l , mid-1) && dfs(postorder , mid , r-1);
}
}
8. 有序数组转换成二叉搜索树
class Solution {
public TreeNode sortedArrayToBST(int[] nums) {
if(nums == null || nums.length == 0) return null;
return dfs(nums , 0 , nums.length-1);
}
TreeNode dfs(int[] nums, int l , int r){
if(l > r) return null;
int mid = l + r >> 1;
TreeNode root = new TreeNode(nums[mid]);
root.left = dfs(nums , l , mid-1);
root.right = dfs(nums , mid + 1, r);
return root;
}
}
9. 有序链表转换成二叉搜索树
class Solution {
public TreeNode sortedListToBST(ListNode head) {
if(head == null) return null;
return dfs(head , null);
}
TreeNode dfs(ListNode head , ListNode tail){
if(head == tail) return null;
ListNode fast = head;
ListNode slow = head;
while(fast.next != tail && fast.next.next != tail){
fast = fast.next.next;
slow = slow.next;
}
TreeNode root = new TreeNode(slow.val);
root.left = dfs(head,slow);
root.right = dfs(slow.next , tail);
return root;
}
}
10. 二叉搜索树的最近公共祖先
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root == null) return root;
if(root.val < p.val && root.val < q.val) return lowestCommonAncestor(root.right,p,q);
else if(root.val > p.val && root.val > q.val) return lowestCommonAncestor(root.left , p , q);
else return root;
}
}