algorithm - 给定一个包含 n 个点的数组,两点之间的距离定义为 min(abs(x1-x2), abs(y1-y2)) 。找到第 k 个最小距离
问题描述
我已经使用最大优先级队列解决了这个问题。我所做的是通过迭代所有可能的对来不断插入距离,直到它的大小变为 k。然后,如果我发现当前距离大于 max-heap 顶部,我会弹出 max-heap 并插入这个距离。然后在迭代所有可能的对之后,最大堆顶部将是我们的答案。这个解决方案的时间复杂度似乎是 O(n^2 logn) 和空间复杂度 O(k)。但我需要做得比这更好吗?还有什么其他方法?
以下是代码快照:
int kthMin(vector<pair<int,int>> Points, int k) {
priority_queue pq;
for(int i=0;i<Points.size()-1; i++) {
for(int j=i+1; j<Points.size(); j++) {
int dist = min( abs(Points[i].first - Points[j].first), abs(Points[i].second - Points[j].second));
if(pq.size()<k) pq.push(dist);
else if(dist< pq.top()) {
pq.pop();
pq.push(dist);
}
}
}
return pq.top();
}
解决方案
这是一种更快的方法。快多少很难说,我的猜测可能是O(n^(3/2) log(n))
.
首先将所有点粘贴到四叉树中。让四叉树中的每个节点包含矩形中点的数量以及 x 和 y 的最小值和最大值作为元信息。
现在你的逻辑看起来像这样。
lower = 0
upper = max(tree.max_x - tree.min_x, tree.max_y - tree.min_y)
while lower < upper:
mid = (lower + upper) / 2
max_below = lower
min_above = upper
count_below = 0
count_at = 0
stack = new stack
stack.push((tree, tree)) # To order them,
while stack is not empty:
# We want ordered "pairs of points of interest" meaning
# p1 in tree1, p2 in tree2 and either p1.x < p2.x
# or p1.x = p2.x and p1.y <= p2.y.
(tree1, tree2) = stack.pop()
if no pairs of points of interest (eg tree2.max_x < tree1.min_x):
pass
elsif all of tree1 within distance mid of all of tree2:
count_below += tree1.count * tree2.count
if max_below < max possible distance from tree1 to tree2:
max_below = max possible distance from tree1 to tree2
elsif all of tree1 at distance mid of all of tree2:
count_at += tree1.count * tree2.count
elsif all of tree1 more than distance mid of all of tree2:
if min possible distance from tree1 to tree2 < min_above:
min_above = min possible distance from tree1 to tree2
elsif longest axis of tree1 longer than longest axis of tree2:
for child of tree1:
stack.push((child, tree2))
else:
for child of tree2:
stack.push((tree1, child))
if k < count_below:
upper = max_below
elsif k <= count_below + count_at:
return mid
else:
lower = min_above
这个想法是您的二进制搜索“捕捉”到O(n^2)
可能的距离之一。因此,经过O(log(n))
对数次搜索后,您会找到正确的。并且每次搜索本身都会尽可能地尝试以块为单位计算数字。(四叉树结构有帮助。)
祝你好运,使这个轮廓精确!
推荐阅读
- javascript - 下拉菜单在 Chrome 中显示正常,但在 Safari 中不显示(由图像覆盖)
- javascript - RegExp (javascript) :: find a group of php variables including the $ character (Enlighter JS)
- python - Python - TypeError: super(type, obj): obj 必须是类型的实例或子类型?
- list - 换行符不适用于嵌入消息中的列表 - Discord.py
- c# - 选择带有复选框的列表视图行
- python - 什么是打印功能中的冲洗?
- python - 我可以在使用存储变量时保持 tkinter 窗口打开吗?
- javascript - 无法在 Google Chart 上为 Tree Map 设置内部 HTML
- ruby-on-rails - 有没有办法在查询中修改 .where() 查询的数据库端?
- c++ - 如何在 C++ 中为定义找到像 0x000000 这样的值?