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;
}