您的位置:首页 > 产品设计 > UI/UE

Leetcode: Closest Binary Search Tree Value II

2015-12-24 13:14 537 查看
Given a non-empty binary search tree and a target value, find k values in the BST that are closest to the target.

Note:
Given target value is a floating point.
You may assume k is always valid, that is: k ≤ total nodes.
You are guaranteed to have only one unique set of k values in the BST that are closest to the target.
Follow up:
Assume that the BST is balanced, could you solve it in less than O(n) runtime (where n = total nodes)?


Hint:

Consider implement these two helper functions:
getPredecessor(N)
, which returns the next smaller node to N.

getSuccessor(N)
, which returns the next larger node to N.

Try to assume that each node has a parent pointer, it makes the problem much easier.

Without parent pointer we just need to keep track of the path from the root to the current node using a stack.

You would need two stacks to track the path in finding predecessor and successor node separately.

用一个栈一个队列,用recursion写inorder Traversal, Time: O(N+K), Space: O(N)

/**
* Definition for a binary tree node.
* public class TreeNode {
*     int val;
*     TreeNode left;
*     TreeNode right;
*     TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public List<Integer> closestKValues(TreeNode root, double target, int k) {
List<Integer> res = new ArrayList<Integer>();
LinkedList<Integer> stack = new LinkedList<Integer>();
LinkedList<Integer> queue = new LinkedList<Integer>();
inorder(root, target, stack, queue);
for (int i=0; i<k; i++) {
if (stack.isEmpty()) res.add(queue.poll());
else if (queue.isEmpty()) res.add(stack.pop());
else {
int s = stack.peek();
int q = queue.peek();
if (Math.abs(s-target) < Math.abs(q-target)) {
res.add(s);
stack.pop();
}
else {
res.add(q);
queue.poll();
}
}
}
return res;
}

public void inorder(TreeNode root, double target, LinkedList<Integer> stack, LinkedList<Integer> queue) {
if (root == null) return;
inorder(root.left, target, stack, queue);
if (root.val < target) {
stack.push(root.val);
}
else {
queue.offer(root.val);
}
inorder(root.right, target, stack, queue);
}
}


Better Idea: 只用一个大小为K的队列的方法:Time O(N), Space O(K)

前K个数直接加入队列,之后每来一个新的数(较大的数),如果该数和目标的差,相比于队头的数离目标的差来说,更小,则将队头拿出来,将新数加入队列。如果该数的差更大,则直接退出并返回这个队列,因为后面的数更大,差值也只会更大。

/**
* Definition for a binary tree node.
* public class TreeNode {
*     int val;
*     TreeNode left;
*     TreeNode right;
*     TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public List<Integer> closestKValues(TreeNode root, double target, int k) {
//List<Integer> res = new ArrayList<Integer>();
LinkedList<TreeNode> stack = new LinkedList<TreeNode>();
LinkedList<Integer> queue = new LinkedList<Integer>();

while (!stack.isEmpty() || root!=null) {
if (root != null) {
stack.push(root);
root = root.left;
}
else {
root = stack.pop();
if (queue.size() < k) {
queue.offer(root.val);
}
else {
if (Math.abs(root.val-target) < Math.abs(queue.peek()-target)) {
queue.poll();
queue.offer(root.val);
}
else break;
}
root = root.right;
}
}

return (List<Integer>)queue;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: