LeetCode 直线上最多的点数

给定一个二维平面,平面上有 n 个点,求最多有多少个点在同一条直线上。

示例 1:

输入: [[1,1],[2,2],[3,3]]
输出: 3
解释:
^
|
|        o
|     o
|  o  
+------------->
0  1  2  3  4

示例 2:

输入: [[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]]
输出: 4
解释:
^
|
|  o
|     o        o
|        o
|  o        o
+------------------->
0  1  2  3  4  5  6

思路分析:一条直线可有一个点和斜率确定,然而斜率可能不是整数,所以对于斜率的处理保存很困难。
但是因为斜率是由Δy/Δx计算得到的,那么可以采用<Δx,Δy>到个数的映射,
不过需要将Δx,Δy化为最简的形式,这样,就可以将<Δx,Δy>这个数值对相等看成是斜率相等。

/**
 * Definition for a point.
 * struct Point {
 *     int x;
 *     int y;
 *     Point() : x(0), y(0) {}
 *     Point(int a, int b) : x(a), y(b) {}
 * };
 */
class Solution {
public:
	//辗转相除法求最大公约数
	int gcd(int a, int b)
	{
		if (b == 0)
			return a;
		else
			return gcd(b, a % b);
	}
	int maxPoints(vector<Point>& points) {
		int result = 0;
		int pointsSize = points.size();
		for (int i = 0; i < pointsSize; ++i) {
            //固定points[i],遍历其他点,记录不同斜率个数,寻找斜率相同的直线中过点最多的
			int tempRes = 0;//实时更新,当前直线中过点最多的
			int samePointCnt = 0;//与points[i]重复的点个数
			map<pair<int, int>, int> myMap;//<Δx,Δy>与其出现的次数关联
			for (int j = i + 1; j < pointsSize; ++j) {
				if (points[i].x == points[j].x && points[i].y == points[j].y) {//记录重合点
					++samePointCnt;
				}
				else {
					int xx = points[i].x - points[j].x;
					int yy = points[i].y - points[j].y;
					int maxDivisor = gcd(xx, yy);//计算最大公约数
					xx /= maxDivisor;//化简
					yy /= maxDivisor;
					tempRes = max(tempRes, ++myMap[make_pair(xx, yy)]);
				}
			}
            //tempRes + samePointCnt + 1这里需要加上重复的点、和自己
			result = max(result, tempRes + samePointCnt + 1);
		}
		return result;
	}
};

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_41855420/article/details/87903271