一面试题,大家来试试最优解法

我真的不是菜鸟 2014-04-15 04:46:56
在一个平面上有N个坐标 x1,y1 x2,y2.......... 给出一个坐标,在N个内找到离指定坐标最近的一个。

下面是我的解法:

        double GetDistance(Point p1, Point p2)
{
return Math.Sqrt(Math.Pow(p1.X - p2.X, 2) + Math.Pow(p1.Y - p2.Y, 2));
}

Point Fun(List<Point> pArray, Point p)
{
int MinIndex = 0;
double MinDistance = GetDistance(pArray[MinIndex], p);
double Dinstance;
for (int i = 1; i < pArray.Count; i++)
{
Dinstance = GetDistance(pArray[i], p);
if (Dinstance < MinDistance)
{
MinIndex = i;
MinDistance = Dinstance;
}
}
return pArray[MinIndex];
}


这些的写法是没问题,是能找出最近的一个坐标,但面试官说我这个方法挺笨的,要遍历所有的坐标。
说可以把坐标分成两部分,而且也不用全部遍历所有坐标就能找到一个最近点。

按照面试官的提示,也上网搜了下,貌似是和"分治法"有关。 但小弟不是很懂,所有发到论坛上面请大家讨论下。看下各位还有没有最优的解法,谢谢大家!

200分奉上! 欢迎大家来讨论
...全文
768 27 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
new_dai 2014-04-19
  • 打赏
  • 举报
回复
“不全部遍历所有坐标点”是不可能的。任何一种预处理(比如说按照x和y排序)都需要遍历所有坐标点。不进行预处理,什么“把坐标分成两部分”这就是不合逻辑的话。 实际上,假设你计算出来第一个参考点距离目标点的距离是a,那么你只需要过滤剩下 x<=a && y<=a 的点了,其它的点就可以删除掉了。 如果所有点都被删除掉了,那么这个参考点就是要找的。 否则可以迭代这个做法。
h598937749 2014-04-18
  • 打赏
  • 举报
回复
你面试什么?
jdczp 2014-04-18
  • 打赏
  • 举报
回复
你拿本书盖住一半,让面试官说出盖住的都有些什么字,面试官如果说不知道,你就给他说你不是有算法吗?算算看。
於黾 2014-04-18
  • 打赏
  • 举报
回复
还有可以在判断中进一步优化代码 在取得当前遍历的点中最近的点后,下一个点先判断横纵坐标是否大于已知距离,如果已经大了,就根本不需要再平方相加了.
於黾 2014-04-18
  • 打赏
  • 举报
回复
"不用全部遍历所有坐标就能找到一个最近点" 这不科学啊. 如果有一个点,你根本没有对它进行判断,你怎么知道它不是最近的呢. 所以考官的意思应该是:并不是不对坐标进行判断,而是不要直接进行计算去验证,而是用一个算法先排除掉大部分的点. 我比较倾向于三角形验证,先把两边之和明显过大的点排除掉,在剩下的点中找平方和最小的.
zhou09039051698 2014-04-18
  • 打赏
  • 举报
回复
把开方去掉,LZ的算法是完美的。。。
般若-金刚 2014-04-17
  • 打赏
  • 举报
回复
引用 17 楼 vb763305825 的回复:
[quote=引用 12 楼 u014740916 的回复:] 主考官真是沙场宿将老谋深算以给定点向上下两边寻找可以不用遍历取X轴差距最小并且Y轴差距最小很快的。
这个也得遍历一下吧? 毕竟做X轴和Y轴都不是有序数组, 请问能详细点说说吗?[/quote] 嗯,当时应该是脑中第一推理印象,毕竟没去实证,如果要实证先要画出图来分析,分析普通的点和极端的点(给定点) 分析普通的分布和极端分布。最后找到可能的最优方案再写程序。
欢乐的小猪 2014-04-16
  • 打赏
  • 举报
回复
数据没有预处理,必须要遍历 吖
showjim 2014-04-16
  • 打赏
  • 举报
回复
一次性的查找只能循环遍历。 面试官应该需要的是能够重复使用的查询调用,可使用KD tree或者Rtree之类的数据结构。
般若-金刚 2014-04-16
  • 打赏
  • 举报
回复
主考官真是沙场宿将老谋深算以给定点向上下两边寻找可以不用遍历取X轴差距最小并且Y轴差距最小很快的。
张大吉001 2014-04-16
  • 打赏
  • 举报
回复
太伤脑筋了
WM_JAWIN 2014-04-16
  • 打赏
  • 举报
回复
先算出一点的距离 L, 然后遍历, 判断, Xn-X0 或 Yn-Y0 的绝对值是否大于L 大于L,进下一点 小于等L,计算实际距离Ln 判断Ln与L的值,根据情况接着处理 这样处理地,应该会比楼主的效率要高,
七神之光 2014-04-16
  • 打赏
  • 举报
回复
不遍历 没法做 分治算法如下
首先划分集合S为SL和SR,使得SL中的每一个点位于SR中每一个点的左边,并且SL和SR中点数相同。分别在SL和SR中解决最近点对问题,得到DL和DR,分别表示SL和SR中的最近点对的距离。令d=min(DL,DR)。如果S中的最近点对(P1,P2)。P1、P2两点一个在SL和一个在SR中,那么P1和P2一定在以L为中心的间隙内,以L-d和L+d为界,如下图所示:

                       

     如果在SL中的点P和在SR中的点Q成为最近点对,那么P和Q的距离必定小于d。因此对间隙中的每一个点,在合并步骤中,只需要检验yp+d和yp-d内的点即可。

步骤1:根据点的y值和x值对S中的点排序。

步骤2:找出中线L将S划分为SL和SR

步骤3:将步骤2递归的应用解决SL和SR的最近点对问题,并令d=min(dL,dR)。

步骤4:将L-d~L+d内的点以y值排序,对于每一个点(x1,y1)找出y值在y1-d~y1+d内的所有点,计算距离为d'。                 如果d'小于d,令d=d',最后的d值就是答案。
  • 打赏
  • 举报
回复
学习了。 给力啊!
  • 打赏
  • 举报
回复
引用 12 楼 u014740916 的回复:
主考官真是沙场宿将老谋深算以给定点向上下两边寻找可以不用遍历取X轴差距最小并且Y轴差距最小很快的。
这个也得遍历一下吧? 毕竟做X轴和Y轴都不是有序数组, 请问能详细点说说吗?
volte 2014-04-16
  • 打赏
  • 举报
回复
引用 8 楼 sp1234 的回复:
如果没有删除掉任何的点,这个时候才需要计算另一个从未选择过的参考点距离目标点的距离。然后继续迭代 如果所有点都计算过距离目标点的距离了,此时所有的剩下的点距离目标点的距离都计算过了,那么你可以直接根据删选一个最短距离的点。
这位大哥的算法可行度高
youzelin 2014-04-16
  • 打赏
  • 举报
回复
其他的不说,其实要测算最近距离,根本不用 Math.Sqrt。平方和大,Math.Sqrt 一定大。你觉得是不是?所以这步 Sqrt 多余的,而且影响性能
jy251 2014-04-15
  • 打赏
  • 举报
回复
我又想了下,难道你的考官是想让你用二分查找? 线X轴查找,再Y轴查找? 二分查找要有前提的,又不是什么时候都能用
jy251 2014-04-15
  • 打赏
  • 举报
回复
mark一下, 我想看看有没有人能给出不遍历的方法·····
  • 打赏
  • 举报
回复
如果没有删除掉任何的点,这个时候才需要计算另一个从未选择过的参考点距离目标点的距离。然后继续迭代 如果所有点都计算过距离目标点的距离了,此时所有的剩下的点距离目标点的距离都计算过了,那么你可以直接根据删选一个最短距离的点。
加载更多回复(7)

111,098

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧