Closest Binary Search Tree Value
所谓 “最近的点”,可能是 parent ,可能是 child,可能在左边,也可能在右边。
-
所以一要存好 prev;
-
二要两边都探,不能沿着一边硬走。
-
为什么写成两个函数?因为这里是preorder traversal!
double dif=Double.MAX_VALUE;
int nodeval=0;
public int closestValue(TreeNode root, double target) {
helper(root,target);
return nodeval;
}
private void helper(TreeNode root,double target){
if(root==null) return;
if(target==root.val){
nodeval=root.val;
return;
}
if(Math.abs(target-root.val)<dif){
dif=Math.abs(target-root.val);
nodeval=root.val;
}
helper(root.left,target);
helper(root.right,target);
}
}
Validate Binary Search Tree
利用 Integer 是 object 的性质,用 null reference 代表开区间。从root开始遍历。
public class Solution {public boolean isValidBST(TreeNode root) {
return isValidBST(root, null, null);
}
private boolean isValidBST(TreeNode root, Integer max, Integer min){
if (root == null){
return true;
}
// 如果该节点大于上限 返回假
if (max != null && root.val >= max){ //root.val是左子树的max 右侧的max是root的值,max应该比左边要大才对
return false;
}
// 如果该节点小于下限 返回假
if (min != null && root.val <= min){ //root.val是右子树的value 右侧的min是root的值,min应该比左边要小才对(min比右子树最小的还要小)
return false;
}
// 递归判断左子树和右子树
return isValidBST(root.left, root.val, min) && isValidBST(root.right, max, root.val);
}
}
public boolean isValidBST(TreeNode root) {
if (root == null) return true;
Stack<TreeNode> stack = new Stack<>();
TreeNode pre = null;
while (root != null || !stack.isEmpty()) {
while (root != null) {
stack.push(root);
root = root.left;
}
root = stack.pop();
if(pre != null && root.val <= pre.val) return false;
pre = root;
root = root.right;
}
return true;
}
Kth Smallest Element in a BST
这题考察的就是 BST 的性质: in order = sorted.
另一种应对多次查询的好办法是 augmented binary tree; 第一次用 O(n) 的时间统计记录一下每个 node 左子树节点个数,后面的每次查询就可以 O(height) 的时间搜索了。
public class Solution {
public int kthSmallest(TreeNode root, int k) {
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode cur = root;
while(cur != null || !stack.isEmpty()){
while(cur != null){
stack.push(cur);
cur = cur.left;
}
TreeNode node = stack.pop();
if(--k == 0) return node.val;
cur = node.right;
}
return root.val;
}
}
Inorder Successor in BST
简单写法是 naive 的in order traversal. 只要是 binary tree 都可以用。
public class Solution {
public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode cur = root;
boolean reachedP = false;
while(cur != null || !stack.isEmpty()){
while(cur != null){
stack.push(cur);
cur = cur.left;
}
TreeNode node = stack.pop();
if(reachedP) return node;
if(node == p) reachedP = true;
cur = node.right;
}
return null;
}
}
-
不过这题还可以进一步利用 BST 的性质,用模板从root开始遍历,每一次把比p.val稍大的那个root.val给记录下来。
public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
TreeNode res = null;
while(root!=null) {
if(root.val > p.val) {
res = root;
root = root.left;
}
else root = root.right;
}
return res;
}
Convert Sorted Array to Binary Search Tree
利用 BST inorder = sorted 的性质,一道很有意思的递归题。
在 BST 里多用区间的思想思考问题。
public class Solution {
public TreeNode sortedArrayToBST(int[] nums) {
return helper(nums, 0, nums.length - 1);
}
private TreeNode helper(int[] nums, int start, int end){
if(start > end) return null;
if(start == end) return new TreeNode(nums[start]);
int mid = start + (end - start) / 2;
TreeNode root = new TreeNode(nums[mid]);
root.left = helper(nums, start, mid - 1);
root.right = helper(nums, mid + 1, end);
return root;
}