C# 计算同一行上的最大点数(Count maximum points on same line)

示例图 

        给定二维平面上的 N 点作为一对 (x, y) 坐标,我们需要找到位于同一条线上的最大点数。

例子: 

输入:points[] = {-1, 1}, {0, 0}, {1, 1}, 
                    {2, 2}, {3, 3}, {3, 4}

输出:4

        那么位于同一条线上的点的最大数量为 4,这些点分别是 {0, 0}, {1, 1}, {2, 2}, {3, 3}

        我们可以通过以下方法解决上述问题 - 对于每个点 p,计算其与其他点的斜率,并使用地图记录有多少个点具有相同的斜率,通过这种方式我们可以找出有多少个点与 p 在同一条线上。对于每个点继续执行相同的操作并更新迄今为止找到的最大点数。

实施过程中需要注意以下几点: 

    1、如果两个点是 (x1, y1) 和 (x2, y2),则它们的斜率将是 (y2 – y1) / (x2 – x1),这可能是一个双精度值,并且可能导致精度问题。为了消除精度问题,我们将斜率视为对 ((y2 – y1), (x2 – x1)) 而不是比率,并在插入到映射之前通过它们的 gcd 减少对。在下面的代码点中,垂直或重复的点被单独处理。

    2、如果我们使用c++ 中的 unordered_mapJava 中的 HashMap来存储斜率对,则解决方案的总时间复杂度将为 O(n^2),空间复杂度将为 O(n)。

示例代码:

/* C# program to find maximum number of point
which lie on same line */
using System;
using System.Collections.Generic;
 
class GFG {
 
  static int gcd(int p, int q)
  {
    if (q == 0) {
      return p;
    }
 
    int r = p % q;
 
    return gcd(q, r);
  }
 
  static int N = 6;
 
  // method to find maximum collinear point
  static int maxPointOnSameLine(int[, ] points)
  {
    if (N < 2)
      return N;
 
    int maxPoint = 0;
    int curMax, overlapPoints, verticalPoints;
 
    Dictionary<string, int> slopeMap
      = new Dictionary<string, int>();
 
    // looping for each point
    for (int i = 0; i < N; i++) {
      curMax = overlapPoints = verticalPoints = 0;
 
      // looping from i + 1 to ignore same pair again
      for (int j = i + 1; j < N; j++) {
        // If both point are equal then just
        // increase overlapPoint count
        if (points[i, 0] == points[j, 0]
            && points[i, 1] == points[j, 1])
          overlapPoints++;
 
        // If x co-ordinate is same, then both
        // point are vertical to each other
        else if (points[i, 0] == points[j, 0])
          verticalPoints++;
 
        else {
          int yDif = points[j, 1] - points[i, 1];
          int xDif = points[j, 0] - points[i, 0];
          int g = gcd(xDif, yDif);
 
          // reducing the difference by their gcd
          yDif /= g;
          xDif /= g;
 
          // Convert the pair into a string to use
          // as dictionary key
          string pair = Convert.ToString(yDif)
            + " "
            + Convert.ToString(xDif);
          if (!slopeMap.ContainsKey(pair))
            slopeMap[pair] = 0;
 
          // increasing the frequency of current
          // slope in map
          slopeMap[pair]++;
          curMax
            = Math.Max(curMax, slopeMap[pair]);
        }
 
        curMax = Math.Max(curMax, verticalPoints);
      }
 
      // updating global maximum by current point's
      // maximum
      maxPoint = Math.Max(maxPoint,
                          curMax + overlapPoints + 1);
      slopeMap.Clear();
    }
 
    return maxPoint;
  }
 
  // Driver code
  public static void Main(string[] args)
  {
 
    int[, ] points = { { -1, 1 }, { 0, 0 }, { 1, 1 },
                      { 2, 2 },  { 3, 3 }, { 3, 4 } };
 
    Console.WriteLine(maxPointOnSameLine(points));
  }
}
 
// This code is contributed by phasing17

输出:
4

时间复杂度: O(n 2 logn),其中 n 表示字符串长度。

辅助空间:O(n)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值