Closest Pair of Points | O(nlogn) Implementation
We are given an array of n points in the plane, and the problem is to find out the closest pair of points in the array.This problem arises in a number of applications.For example, in air-traffic control, you may want to monitor
planes that come too close together, since this may indicate a possible collision. Recall the following formula for distance between two points p and q.
We have discussed adivide and conquer solutionfor this problem. The time complexity of the implementation provided
in the previous post is O(n (Logn)^2). In this post, we discuss an implementation with time complexity as O(nLogn).
Following is a recap of the algorithm discussed in the previous post.
1)We sort all points according to x coordinates.
2)Divide all points in two halves.
3)Recursively find the smallest distances in both subarrays.
4)Take the minimum of two smallest distances. Let the minimum be d.
5)Create an array strip[] that stores all points which are at most d distance away from the middle line dividing the two sets.
6)Find the smallest distance in strip[].
7)Return the minimum of d and the smallest distance calculated in above step 6.
The great thing about the above approach is, if the array strip[] is sorted according to y coordinate, then we can find the smallest distance in strip[] in O(n) time. In the implementation discussed in previous post, strip[] was explicitly sorted in every
recursive call that made the time complexity O(n (Logn)^2), assuming that the sorting step takes O(nLogn) time.
In this post, we discuss an implementation where the time complexity is O(nLogn). The idea is to presort all points according to y coordinates. Let the sorted array be Py[]. When we make recursive calls, we need to divide points of Py[] also according to the
vertical line. We can do that by simply processing every point and comparing its x coordinate with x coordinate of middle line.
本题是前一题的二分法的改进,前一个算法的效率是O(nlgnlgn)
前一遍二分法:http://blog.csdn.net/kenden23/article/details/20737523
为什么这个二分法是O(nlgnlgn)呢?除了使用公式计算之外,也可以这么考虑最坏情况,当距离中点的小于d距离,集中了所有的点,那么每次递归都需要对所有的点进行一次排序,效率是O(nlgn),那么每次二分都需要这么的效率,就要乘以做二分法的lgn效率,那么总效率就是O(nlgnlgn)。
呵呵,不是很正规的分析,不过我觉得这么分析更“聪明”,而且不会有错的。
那么为什么很多书上都说这个算法是O(nlgn)呢?因为大多书本都没有分析计算中间点最小距离的时候会出现最坏情况。
而Geeks这个网站考虑的非常仔细,这也是我也很推崇这个网站的原因之一。
本算法提高效率到O(nlgn),就是省去了中间需要重复排序的步骤。如果熟悉了前面的二分法算法,那么就很容易写出这个程序了。不明白的,先搞懂前面的算法,在来改进成这个算法。
修改的地方都注释好了:
struct Point
{
int x, y;
};
int xCompare(const void *a, const void *b)
{
const Point *p1 = (const Point*)a;
const Point *p2 = (const Point*)b;
return p1->x - p2->x;
}
int yCompare(const void *a, const void *b)
{
const Point *p1 = (const Point*)a;
const Point *p2 = (const Point*)b;
return p1->y - p2->y;
}
float squDist(Point &a, Point &b)
{
return float(a.x - b.x)*(a.x - b.x) + float(a.y - b.y)*(a.y - b.y);
}
#include<stdlib.h>
#include<math.h>
float bruteSolve(Point P[], int n)
{
float clo_dist = FLT_MAX;
for (int i = 0; i < n; i++)
{
for (int j = i+1; j < n; j++)
{
float t = squDist(P[i], P[j]);
if (clo_dist > t) clo_dist = t;
}
}
return clo_dist;
}
float midClosest(Point P[], int n, float d)
{
//qsort(P, n, sizeof(Point), yCompare);已经sort好了,不用这句,所以提高了效率
for (int i = 0; i < n; i++)
{
for (int j = i+1; j < n && P[j].y - P[i].y < d; j++)
{
float t = squDist(P[j], P[i]);
if (t < d) d = t;
}
}
return d;
}
float squClosest(Point Px[], Point Py[], int n)
{
if (n <= 3) return bruteSolve(Px, n);
int m = n>>1;;
float ld = squClosest(Px, Py, m);
float rd = squClosest(Px+m, Py, n-m);
float d = ld < rd? ld:rd;
Point *strip = new Point[n];
int j = 0;
for (int i = 0; i < n; i++)
if (abs(Py[i].x - Px[m].x) < d) strip[j++] = Py[i];
float t = midClosest(strip, j, d);
return d < t? d:t;
}
float closest(Point P[], int n)
{
qsort(P, n, sizeof(Point), xCompare);
Point *Py = new Point[n];//增加一个Py,按y排序好的点,所以提高了效率
for (int i = 0; i < n; i++)
Py = P;
return sqrt(squClosest(P, Py, n));
}
分享到:
相关推荐
【标题】"2022最新版:GEEKS V1.0.10主题:在线学习市场WordPress主题.rar" 涉及的核心知识点主要集中在WordPress主题开发与在线教育平台的构建上。WordPress是一个非常流行的开源内容管理系统(CMS),被广泛用于...
- "interview-practice":暗示这个项目可以帮助开发者准备技术面试,因为面试通常会考察候选人的算法理解和实现能力。 【压缩包子文件的文件名称列表】:geeks_algorithms-master 这个列表表明压缩包包含了一个名...
《C++解题指南:Geeks-for-Geeks问题解决方案详解》 在编程的世界里,Geeks-for-Geeks(GFG)是一个备受推崇的学习平台,尤其对于初学者和有经验的开发者来说,这里提供了丰富的算法和数据结构题目。本资料包"geeks...
"Geeks2TheRescue:使用MERN的Web App,旨在连接雄心勃勃的开发人员" 这个标题揭示了项目的核心——一个基于MERN技术栈的Web应用程序,其目的是为了建立一个社区,将充满激情和抱负的开发者联系起来。MERN是一个流行...
带有React JS的WebApp样板 要求: 确保您使用的是节点版本10 安装软件包: $ npm install 创建一个.env文件: $ cp .env.example .env 开始编码! 以及具有实时重新加载功能的webpack开发服务器(适用于Windows...
夏季极客提交 这个Web应用程序被配制成在Innnovaccer SDE实习分配的一部分,使用的NodeJS,MongoDB的,NodeMailer的电子邮件和Nexmo的手机信息,根据。 预习 报到表格 结帐电子邮件 使用的技术 ...
《Geeks3D Furmark:全面解析OpenGL显卡基准测试工具》 Geeks3D Furmark,这是一款专为评测显卡性能而设计的OpenGL基准测试工具,它由知名技术团队Geeks3D开发,旨在为用户提供准确且全面的显卡性能评估。V1.17.1的...
面试时,面试官可能会从多个方面考察候选人的 Java 技能,包括基础语法、类、对象、变量、字符串处理、多线程、面向对象概念、异常处理、集合框架等。 1. **Java 基础**: - Java 是一种静态类型的、解释型的、跨...
欢迎来到4Geeks学院 <\编码时间>内容关于。创始人。团队。奖项。校友关于4Geeks是一家大公司,感觉就像一家小公司;每个人都可以访问,我们喜欢与人接触,我们相信量身定制的教育,而不会离开您的工作,并且100%...
:sparkles: gloomhaven-geeks :sparkles: 这是一个使用Git作为的网站。 它是在不到一分钟的时间内使用创建的。 您可以像这样,或探索一些变体。 如何不同: :artist_palette: 看 :pencil: 内容管理系统 :gear: 静态...
标题中的“geeks文档.doc”和描述中的“geek极客们都用什么神器,这篇文章给了你答案。”都指向了一个主题:探讨极客们使用的高效工具,即“神器”。标签中的“geek 极客 神器”进一步确认了这个话题,我们将重点...
首先,从标题和描述中,我们可以了解到这是关于一个在线IT资源平台geeksforgeeks上关于C++编程语言的学习内容和经验分享。从“标题”中我们得知这是一个专门讨论C++的资源集合,而“描述”部分则是一个学习者的个人...
极客换极客 Geeks-For-Geeks 实习文章 使用 scapy 嗅探数据包 - 使用 Javascript 和 DOM 创建棋盘模式 - 如何将链接从一个 iframe 加载到另一个 iframe -
### Ubuntu Linux for Non-Geeks:重要知识点概览 #### 一、书籍基本信息与版权说明 - **书名**:《Ubuntu Linux for Non-Geeks》 - **作者**:Rickford Grant - **出版社**:No Starch Press - **出版地**:美国...
最短路径的O(ElgV)的解法。 使用邻接表存储图,使用堆操作选取下一个最小路径点。 本题的难度并不在最短路径本身这个算法,而是在于堆的操作: 1 使用双重指针操作堆的节点,可以省去直接复制操作堆节点,提高...
标题中的“Hash Map for geeks_hashmap_Geeks_源码”显然指的是一个关于哈希映射(HashMap)的学习资源,特别针对极客和普通程序员。哈希映射是一种数据结构,它允许我们以O(1)的时间复杂度进行插入、删除和查找操作...
Hardware Hacking Projects for Geeks 英文chm 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载自网络,如有侵权,请联系上传者或csdn删除
### Ubuntu for Non-Geeks (Fourth Edition):一本无痛高效指南 #### 书籍概览 《Ubuntu for Non-Geeks》(第四版)是一本针对Ubuntu新手的实用指南,旨在帮助那些对技术不太熟悉的用户轻松掌握Ubuntu操作系统。...
1. 题目知识点:Cooking for Geeks(为极客烹饪)是一本由Jeff Potter编写的书籍。这本书旨在结合科学原理、技巧和美食,为科技爱好者提供一个结合其兴趣与烹饪技术的新视角。 2. 食谱和营养:书中不仅仅提供食谱,...
《Geeks3D PhysX FluidMark v1.3.1:显卡性能的深度剖析》 在计算机硬件领域,显卡扮演着至关重要的角色,它不仅负责图形渲染,还承担了复杂的物理运算任务。为了评估显卡的性能,专业工具的运用必不可少。其中,...