BST
二叉查找树(BST):根节点大于等于左子树所有节点,小于等于右子树所有节点。
二叉查找树中序遍历有序。
修剪二叉查找树
669. Trim a Binary Search Tree (Easy)
Input:
3
/ \
0 4
\
2
/
1
L = 1
R = 3
Output:
3
/
2
/
1
题目描述:只保留值在 L ~ R 之间的节点
class Solution {
public TreeNode trimBST(TreeNode root, int L, int R) {
if (null == root) {
return null;
}
if (root.val < L) {
return trimBST(root.right, L, R);
}
if (root.val > R) {
return trimBST(root.left, L, R);
}
root.left = trimBST(root.left, L, R);
root.right = trimBST(root.right, L, R);
return root;
}
}
寻找二叉查找树的第 k 个元素
230. Kth Smallest Element in a BST (Medium)
class Solution {
int num = 0, result;
public int kthSmallest(TreeNode root, int k) {
if (null == root || k <= 0) {
return -1;
}
help(root, k);
return result;
}
public void help(TreeNode root, int k) {
if (root.left != null) {
help(root.left, k);
}
num++;
if (num == k) {
result = root.val;
return ;
}
if (root.right != null) {
help(root.right, k);
}
}
}
把二叉查找树每个节点的值都加上比它大的节点的值
Convert BST to Greater Tree (Easy)
Input: The root of a Binary Search Tree like this:
5
/ \
2 13
Output: The root of a Greater Tree like this:
18
/ \
20 13
先遍历右子树。
class Solution {
int sum = 0;
public TreeNode convertBST(TreeNode root) {
if (null == root) {
return null;
}
help(root);
return root;
}
public void help(TreeNode root) {
if (null == root) {
return ;
}
help(root.right);
sum += root.val;
root.val = sum;
help(root.left);
}
}
二叉查找树的最近公共祖先
235. Lowest Common Ancestor of a Binary Search Tree (Easy)
_______6______
/ \
___2__ ___8__
/ \ / \
0 4 7 9
/ \
3 5
For example, the lowest common ancestor (LCA) of nodes 2 and 8 is 6. Another example is LCA of nodes 2 and 4 is 2, since a node can be a descendant of itself according to the LCA definition.
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (null == root || null == p || null == q) {
return null;
}
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;
}
}
}
二叉树的最近公共祖先
236. Lowest Common Ancestor of a Binary Tree (Medium)
_______3______
/ \
___5__ ___1__
/ \ / \
6 2 0 8
/ \
7 4
For example, the lowest common ancestor (LCA) of nodes 5 and 1 is 3. Another example is LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to the LCA definition.
递归解法:
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null || root == p || root == q) return root;
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);
return left == null ? right : right == null ? left : root;
}
非递归解法:
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (null == root || null == p || null == q) {
return null;
}
Stack<TreeNode> stack1 = new Stack<>();
Stack<TreeNode> stack2 = new Stack<>();
help(stack1, root, p);
help(stack2, root, q);
if (stack1.size() > stack2.size()) {
while (stack1.size() != stack2.size()) {
stack1.pop();
}
} else if (stack1.size() < stack2.size()) {
while (stack1.size() != stack2.size()) {
stack2.pop();
}
}
while (!stack1.isEmpty() && !stack2.isEmpty()) {
if (stack1.peek().val == stack2.peek().val) {
return stack1.peek();
}
stack1.pop();
stack2.pop();
}
return null;
}
public boolean help(Stack<TreeNode> stack, TreeNode root, TreeNode node) {
stack.add(root);
boolean left = false;
boolean right = false;
if (root.val == node.val) {
return true;
}
if (root.left != null) {
left = help(stack, root.left, node);
}
if (root.right != null) {
right = help(stack, root.right, node);
}
if (!left && !right) {
stack.pop();
}
return left || right;
}
}
从有序数组中构造二叉查找树
108. Convert Sorted Array to Binary Search Tree (Easy)
class Solution {
public TreeNode sortedArrayToBST(int[] nums) {
if (null == nums || 0 == nums.length) {
return null;
}
int m = (0 + nums.length) / 2;
TreeNode root = new TreeNode(nums[m]);
root.left = help(nums, 0, m - 1);
root.right = help(nums, m + 1, nums.length - 1);
return root;
}
public TreeNode help(int[] nums, int left, int right) {
if (left > right) {
return null;
}
int m = (left + right) / 2;
TreeNode root = new TreeNode(nums[m]);
root.left = help(nums, left, m - 1);
root.right = help(nums, m + 1, right);
return root;
}
}
根据有序链表构造平衡的二叉查找树
109. Convert Sorted List to Binary Search Tree (Medium)
Given the sorted linked list: [-10,-3,0,5,9],
One possible answer is: [0,-3,9,-10,null,5], which represents the following height balanced BST:
0
/ \
-3 9
/ /
-10 5
class Solution {
public TreeNode sortedListToBST(ListNode head) {
if (null == head) {
return null;
}
return help(head, null);
}
public TreeNode help(ListNode head, ListNode end) {
if (null == head || head == end) {
return null;
}
if (null == head.next) {
return new TreeNode(head.val);
}
ListNode mid = head;
ListNode temp = head;
while (temp != end && temp.next != end) {
mid = mid.next;
temp = temp.next.next;
}
TreeNode root = new TreeNode(mid.val);
root.left = help(head, mid);
root.right = help(mid.next, end);
return root;
}
}
在二叉查找树中寻找两个节点,使它们的和为一个给定值
653. Two Sum IV - Input is a BST (Easy)
Input:
5
/ \
3 6
/ \ \
2 4 7
Target = 9
Output: True
使用中序遍历得到有序数组之后,再利用双指针对数组进行查找。
应该注意到,这一题不能用分别在左右子树两部分来处理这种思想,因为两个待求的节点可能分别在左右子树中。
class Solution {
List<Integer> list = new ArrayList<>();
public boolean findTarget(TreeNode root, int k) {
if (null == root) {
return false;
}
tranverse(root);
for (int i = 0, j = list.size() - 1; i < j;) {
int x = list.get(i);
int y = list.get(j);
if (x + y == k) {
return true;
} else if (x + y > k) {
j--;
} else if (x + y < k) {
i++;
}
}
return false;
}
public void tranverse(TreeNode root) {
if (null == root) {
return ;
}
tranverse(root.left);
list.add(root.val);
tranverse(root.right);
}
}
在二叉查找树中查找两个节点之差的最小绝对值
530. Minimum Absolute Difference in BST (Easy)
Input:
1
\
3
/
2
Output:
1
利用二叉查找树的中序遍历为有序的性质,计算中序遍历中临近的两个节点之差的绝对值,取最小值。
class Solution {
List<Integer> list = new ArrayList<>();
public int getMinimumDifference(TreeNode root) {
int min = Integer.MAX_VALUE;
tranverse(root);
for (int i = 0; i < list.size() - 1; i++) {
min = Math.min(min, Math.abs(list.get(i) - list.get(i + 1)));
}
return min;
}
public void tranverse(TreeNode root) {
if (null == root) {
return ;
}
tranverse(root.left);
list.add(root.val);
tranverse(root.right);
}
}
寻找二叉查找树中出现次数最多的值
501. Find Mode in Binary Search Tree (Easy)
1
\
2
/
2
return [2].
答案可能不止一个,也就是有多个值出现的次数一样多。
class Solution {
List<Integer> list = new ArrayList<>();
int pre = Integer.MIN_VALUE;
int cur = 1;
int max = 0;
public int[] findMode(TreeNode root) {
tranverse(root);
int[] result = new int[list.size()];
for (int i = 0; i < list.size(); i++) {
result[i] = list.get(i);
}
return result;
}
public void tranverse(TreeNode root) {
if (null == root) {
return ;
}
tranverse(root.left);
if (pre == root.val) {
cur++;
} else {
cur = 1;
}
pre = root.val;
if (max == cur) {
list.add(root.val);
} else if (max < cur) {
max = cur;
list.clear();
list.add(root.val);
}
tranverse(root.right);
}
}