Max Points on a Line

描述

Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.

分析

暴力枚举法。两点决定一条直线,n个点两两组合,可以得到12n(n+1)\dfrac{1}{2}n(n+1)条直线,对每一条直线,判断n个点是否在该直线上,从而可以得到这条直线上的点的个数,选择最大的那条直线返回。复杂度O(n^3)

上面的暴力枚举法以“边”为中心,再看另一种暴力枚举法,以每个“点”为中心,然后遍历剩余点,找到所有的斜率,如果斜率相同,那么一定共线对每个点,用一个哈希表,key为斜率,value为该直线上的点数,计算出哈希表后,取最大值,并更新全局最大值,最后就是结果。时间复杂度O(n^2),空间复杂度O(n)

以边为中心

  1. // Max Points on a Line
  2. // 暴力枚举法,以边为中心,时间复杂度O(n^3),空间复杂度O(1)
  3. class Solution {
  4. public:
  5. int maxPoints(vector<Point> &points) {
  6. if (points.size() < 3) return points.size();
  7. int result = 0;
  8. for (int i = 0; i < points.size() - 1; i++) {
  9. for (int j = i + 1; j < points.size(); j++) {
  10. int sign = 0;
  11. int a, b, c;
  12. if (points[i].x == points[j].x) sign = 1;
  13. else {
  14. a = points[j].x - points[i].x;
  15. b = points[j].y - points[i].y;
  16. c = a * points[i].y - b * points[i].x;
  17. }
  18. int count = 0;
  19. for (int k = 0; k < points.size(); k++) {
  20. if ((0 == sign && a * points[k].y == c + b * points[k].x) ||
  21. (1 == sign&&points[k].x == points[j].x))
  22. count++;
  23. }
  24. if (count > result) result = count;
  25. }
  26. }
  27. return result;
  28. }
  29. };

以点为中心

  1. // Max Points on a Line
  2. // 暴力枚举,以点为中心,时间复杂度O(n^2),空间复杂度O(n^2)
  3. class Solution {
  4. public:
  5. int maxPoints(vector<Point> &points) {
  6. if (points.size() < 3) return points.size();
  7. int result = 0;
  8. unordered_map<double, int> slope_count;
  9. for (int i = 0; i < points.size()-1; i++) {
  10. slope_count.clear();
  11. int samePointNum = 0; // 与i重合的点
  12. int point_max = 1; // 和i共线的最大点数
  13. for (int j = i + 1; j < points.size(); j++) {
  14. double slope; // 斜率
  15. if (points[i].x == points[j].x) {
  16. slope = std::numeric_limits<double>::infinity();
  17. if (points[i].y == points[j].y) {
  18. ++ samePointNum;
  19. continue;
  20. }
  21. } else {
  22. if (points[i].y == points[j].y) {
  23. // 0.0 and -0.0 is the same
  24. slope = 0.0;
  25. } else {
  26. slope = 1.0 * (points[i].y - points[j].y) /
  27. (points[i].x - points[j].x);
  28. }
  29. }
  30. int count = 0;
  31. if (slope_count.find(slope) != slope_count.end())
  32. count = ++slope_count[slope];
  33. else {
  34. count = 2;
  35. slope_count[slope] = 2;
  36. }
  37. if (point_max < count) point_max = count;
  38. }
  39. result = max(result, point_max + samePointNum);
  40. }
  41. return result;
  42. }
  43. };

原文: https://soulmachine.gitbooks.io/algorithm-essentials/content/cpp/simulation/max-points-on-a-line.html