简体   繁体   English

查找给定集合中的所有共线点

[英]Find all collinear points in a given set

This is an interview question : "Find all collinear points in a given set".这是一个面试问题:“找到给定集合中的所有共线点”。

As I understand, they ask to print out the points, which lie in the same line (and every two points are always collinear).据我了解,他们要求打印出位于同一条线上的点(每两个点总是共线的)。 I would suggest the following.我建议以下。

  1. Let's introduce two types Line (pair of doubles) and Point (pair of integers).让我们介绍两种类型Line (一对双精度)和Point (一对整数)。
  2. Create a multimap : HashMap<Line, List<Point>)创建多图: HashMap<Line, List<Point>)
  3. Loop over all pairs of points and for each pair: calculate the Line connecting the points and add the line with those points to the multimap.遍历所有点对和每对点:计算连接点的Line并将这些点的线添加到多图。

Finally, the multimap contains the lines as the keys and a list collinear points for each line as its value.最后,多图包含作为键的线和作为其值的每条线的列表共线点。

The complexity is O(N^2).复杂度为 O(N^2)。 Does it make sense ?是否有意义 ? Are there better solutions ?有更好的解决方案吗?

Collinear here doesn't really make sense unless you fix on 2 points to begin with.除非您一开始就固定在 2 个点上,否则这里的共线实际上并没有什么意义。 So to say, "find all collinear points in a given set" doesn't make much sense in my opinion, unless you fix on 2 points and test the others to see if they're collinear.所以说,“找到给定集合中的所有共线点”在我看来没有多大意义,除非你确定 2 个点并测试其他点以查看它们是否共线。

Maybe a better question is, what is the maximum number of collinear points in the given set?也许更好的问题是,给定集合中共线点的最大数量是多少? In that case, you could fix on 2 points (just use 2 loops), then loop over the other points and check that the slope matches between the fixed points and the other points.在这种情况下,您可以固定 2 个点(只需使用 2 个循环),然后遍历其他点并检查固定点和其他点之间的斜率是否匹配。 You could use something like this for that check, assuming the coordinates are integer (you could change parameter types to double otherwise).假设坐标是整数,您可以使用类似的东西进行检查(否则您可以将参数类型更改为双精度)。

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Returns whether 3 points are collinear
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
bool collinear(int x1, int y1, int x2, int y2, int x3, int y3) {
  return (y1 - y2) * (x1 - x3) == (y1 - y3) * (x1 - x2);
}

So the logic becomes:于是逻辑就变成了:

int best = 2;
for (int i = 0; i < number of points; ++i) {
  for (int j = i+1, j < number of points; j++) {
    int count = 2;
    for (int k = 0; i < number of points; ++k) {
      if (k==i || k==j)
        continue;

      check that points i, j and k are collinear (use function above), if so, increment count.
    }
    best = max(best,count); 
  }
}

solve the problem in dual plane, convert all the points in to line segments.解决双平面问题,将所有点转换为线段。 And then run a plane sweep to report all the intersections.然后运行平面扫描以报告所有交叉点。 The lines in the dual plane will pass through same point represents collinear points.双平面中的线将通过同一点表示共线点。 And the plane sweep can be done in O(nlogn) time.平面扫描可以在 O(nlogn) 时间内完成。

Take a look at the two methods described in http://www.cs.princeton.edu/courses/archive/spring03/cs226/assignments/lines.html .看看http://www.cs.princeton.edu/courses/archive/spring03/cs226/assignments/lines.html 中描述的两种方法。

To find 4 or more collinear points given N points, the brute-force method has a time complexity of O(N^4), but a better method does it in O(N^2 log N).要在给定 N 个点的情况下找到 4 个或更多共线点,蛮力方法的时间复杂度为 O(N^4),但更好的方法在 O(N^2 log N) 中完成。

One of interesting solution for this problem is here.这个问题的一个有趣的解决方案是here。

Time complexity is O(n2)时间复杂度为 O(n2)

Space Complexity- O(n)空间复杂度- O(n)

https://stackoverflow.com/a/50207802/7438973 https://stackoverflow.com/a/50207802/7438973

您可以查看我的解决方案https://github.com/boleque/collinear_points ,它基于算法,​​在 coursera 的第一部分普林斯顿课程

I think the intent is to find a line which passes through maximum number of points or identify this set of collinear points.我认为目的是找到一条通过最大点数的线或识别这组共线点。 This link gives a N^2(logN) solution to this problem链接为此问题提供了 N^2(logN) 解决方案

Are you sure your analysis of the runtime is correct?您确定您对运行时的分析是正确的吗? You say to loop over all the pairs of points, of which there are n*(n-1)/2, ie O(n^2).你说循环所有点对,其中有n *(n-1)/ 2,即O(n ^ 2)。 Then you add the line and the pair of points to the map.然后将线和点对添加到地图中。 However, I don't think the time to add such a line + point combination is constant.但是,我认为添加这种线+点组合的时间并不是恒定的。 This means overall your time is O(n^2 log n) not a constant times n^2, which is what O(n^2) means.这意味着您的总体时间是 O(n^2 log n) 而不是常数时间 n^2,这就是 O(n^2) 的意思。

So the real question would be, given that it can be done in time O(n^2 log n) can it be done in time O(n^2).所以真正的问题是,考虑到它可以在 O(n^2 log n) 时间内完成,它是否可以在 O(n^2) 时间内完成。 Clearly O(n^2) gives a lower bound as you must at the very least print out every pair of points, of which there are O(n^2).显然 O(n^2) 给出了一个下限,因为您至少必须打印出每一对点,其中有 O(n^2)。 My feeling is this is a completely general sorting problem and that one cannot expect better than O(n^2 log n) in general.我的感觉是这是一个完全一般的排序问题,一般来说不能期望比 O(n^2 log n) 更好。 However a full proof of that fact may be non-trivial.然而,这一事实的完整证明可能并非易事。

Another thing to beware of is that the set may contain zero or one points, and so you will need to check that your algorithm handles these cases correctly, otherwise write special cases for those.要注意的另一件事是该集合可能包含零或一个点,因此您需要检查您的算法是否正确处理这些情况,否则为这些情况编写特殊情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM