108. Convert Sorted Array to Binary Search Tree
在 BST 里多用区间的思想思考问题。
public class Solution {
public TreeNode sortedArrayToBST(int[] nums) {
if (nums == null || nums.length == 0) return null;
return helper(0, nums.length - 1, nums);
}
private TreeNode helper(int start, int end, int[] nums) {
if (start > end) return null;
int mid = start + (end - start) / 2;
TreeNode left = helper(start, mid - 1, nums);
TreeNode right = helper(mid + 1, end, nums);
TreeNode root = new TreeNode(nums[mid]);
root.left = left;
root.right = right;
return root;
}
}
501. Find Mode in Binary Search Tree
不是很确定这道题和BST的关系,而且用了O(n)的space,不能算作已经做出了这道题。
public class Solution {
public int[] findMode(TreeNode root) {
if (root == null) return new int[0];
Map<Integer, Integer> map = new HashMap<>();
helper(root, map);
int count = 0;
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
if (count < entry.getValue()) {
count = entry.getValue();
}
}
int count2 = 0;
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
if (count == entry.getValue()) {
count2++;
}
}
int[] result = new int[count2];
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
if (count == entry.getValue()) {
result[count2 - 1] = entry.getKey();
count2--;
}
}
return result;
}
private void helper(TreeNode root, Map<Integer, Integer> map) {
if (root == null) return;
helper(root.left, map);
helper(root.right, map);
if (!map.containsKey(root.val)) {
map.put(root.val, 1);
} else {
map.put(root.val, map.get(root.val) + 1);
}
}
}
230. Kth Smallest Element in a BST
这题主要看follow-up,原题没有难度可言。
Follow up:
What if the BST is modified (insert/delete operations) often and you need to find the kth smallest frequently? How would you optimize the kthSmallest routine? 维护一个大小为 k 的 max heap,一直有 insert 的时候好办;有 delete 而且删掉的 node 又在 heap 里就只好找一下 in order successor 了。
06/23 更新:把priority queue的方法写了一下。
public class Solution {
public int kthSmallest(TreeNode root, int k) {
PriorityQueue<TreeNode> pq = new PriorityQueue<>(new Comparator<TreeNode>(){
public int compare(TreeNode node1, TreeNode node2) {
return node1.val - node2.val;
}
});
preOrder(root, pq);
int res = 0;
for (int i = 0; i < k; ++i) {
res = pq.poll().val;
}
return res;
}
private void preOrder(TreeNode root, PriorityQueue<TreeNode> pq) {
if (root == null) return;
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()) {
TreeNode node = stack.pop();
pq.offer(node);
if (node.right != null) stack.push(node.right);
if (node.left != null) stack.push(node.left);
}
}
}
另一种应对多次查询的好办法是 augmented binary tree; 第一次用 O(n) 的时间统计记录一下每个 node 左子树节点个数,后面的每次查询就可以 O(height) 的时间搜索了。
538. Convert BST to Greater Tree / Convert BST to Greater Tree
leetcode的testcase和输出依然有问题,在我看来是有歧义的,应该写作[2,null,3],但是[2,3]也视作合法的。
这和LC108的合法输入输出的规定是不相符的。很明显538还需要进一步修正。
我不太喜欢用global变量,但是一次次代看着比较烦。
public class Solution {
int sum = 0;
public TreeNode convertBST(TreeNode root) {
if (root == null) return root;
convertBST(root.right);
root.val += sum;
sum = root.val;
convertBST(root.left);
return root;
}
}