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

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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