You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

110 lines
3.0 KiB

2 years ago
package class42;
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;
public class Problem_0272_ClosestBinarySearchTreeValueII {
public static class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int val) {
this.val = val;
}
}
// 这个解法来自讨论区的回答,最优解实现的很易懂且漂亮
public static List<Integer> closestKValues(TreeNode root, double target, int k) {
List<Integer> ret = new LinkedList<>();
// >=8最近的节点而且需要快速找后继的这么一种结构
Stack<TreeNode> moreTops = new Stack<>();
// <=8最近的节点而且需要快速找前驱的这么一种结构
Stack<TreeNode> lessTops = new Stack<>();
getMoreTops(root, target, moreTops);
getLessTops(root, target, lessTops);
if (!moreTops.isEmpty() && !lessTops.isEmpty() && moreTops.peek().val == lessTops.peek().val) {
getPredecessor(lessTops);
}
while (k-- > 0) {
if (moreTops.isEmpty()) {
ret.add(getPredecessor(lessTops));
} else if (lessTops.isEmpty()) {
ret.add(getSuccessor(moreTops));
} else {
double diffs = Math.abs((double) moreTops.peek().val - target);
double diffp = Math.abs((double) lessTops.peek().val - target);
if (diffs < diffp) {
ret.add(getSuccessor(moreTops));
} else {
ret.add(getPredecessor(lessTops));
}
}
}
return ret;
}
// 在root为头的树上
// 找到>=target且最接近target的节点
// 并且找的过程中只要某个节点x往左走了就把x放入moreTops里
public static void getMoreTops(TreeNode root, double target, Stack<TreeNode> moreTops) {
while (root != null) {
if (root.val == target) {
moreTops.push(root);
break;
} else if (root.val > target) {
moreTops.push(root);
root = root.left;
} else {
root = root.right;
}
}
}
// 在root为头的树上
// 找到<=target且最接近target的节点
// 并且找的过程中只要某个节点x往右走了就把x放入lessTops里
public static void getLessTops(TreeNode root, double target, Stack<TreeNode> lessTops) {
while (root != null) {
if (root.val == target) {
lessTops.push(root);
break;
} else if (root.val < target) {
lessTops.push(root);
root = root.right;
} else {
root = root.left;
}
}
}
// 返回moreTops的头部的值
// 并且调整moreTops : 为了以后能很快的找到返回节点的后继节点
public static int getSuccessor(Stack<TreeNode> moreTops) {
TreeNode cur = moreTops.pop();
int ret = cur.val;
cur = cur.right;
while (cur != null) {
moreTops.push(cur);
cur = cur.left;
}
return ret;
}
// 返回lessTops的头部的值
// 并且调整lessTops : 为了以后能很快的找到返回节点的前驱节点
public static int getPredecessor(Stack<TreeNode> lessTops) {
TreeNode cur = lessTops.pop();
int ret = cur.val;
cur = cur.left;
while (cur != null) {
lessTops.push(cur);
cur = cur.right;
}
return ret;
}
}