LeetCode.直线上最多的点数 (最大公约数对分数进行约分,自建string作分数)

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

输入: [ [ 1 , 1 ], [ 2 , 2 ], [ 3 , 3 ] ]
输出: 3

class Solution {
private:
	//获取斜率
	//通过string 构造分数,避免精度不正确
	//使用最大公约数化简 分子和分母
	string getK(int y, int x) {
		//y有可能为0,放后面(斜率为0的情况)
		int gcdResult = gcd(abs(x), abs(y));
		//构建斜率,自判断斜率正负
		string result = ((y < 0 && x < 0) || (y > 0 && x > 0)) ? "+" : "-";
		//约分
		result += to_string(abs(y) / gcdResult) + "/" + to_string(abs(x) / gcdResult);
		return result;
	}

	// 最大公约数
	int gcd(int a, int b) {
		if (b == 0)
			return a;
		else
			return gcd(b, a % b);
	}
public:
	int maxPoints(vector<vector<int>>& points) {
		if (points.empty())return 0;
		int result = 0;
		map<string, int> pointMap;//斜率 + 点集合
		for (int i = 0; i < points.size(); ++i)
		{
			int i_x = points[i][0];
			int i_y = points[i][1];
			int tempResult = 0;
			int sampPointNums = 0;//相同位置的点的个数
			int KZeroNums = 0;//斜率为不存在的点的个数(j_x-i_x值为0)
			for (int j = i + 1; j < points.size(); ++j)
			{
				int j_x = points[j][0];
				int j_y = points[j][1];
				if (i_x == j_x && i_y == j_y) 
					++sampPointNums;
				else if (i_x == j_x) 
					++KZeroNums;
				else {
					int tempy = j_y - i_y;
					int tempx = j_x - i_x;
					string&& K = getK(tempy, tempx);
					if (pointMap.find(K) == pointMap.end())
						pointMap[K] = 1;
					else ++pointMap[K];
				}
			}
			//相同斜率的点个数
			for (auto&& iter = pointMap.begin(); iter != pointMap.end(); ++iter)
				if (iter->second > tempResult)
					tempResult = iter->second;
			pointMap.clear();

			//斜率都不存在的点个数
			tempResult = max(tempResult, KZeroNums);
			//相同位置的点个数 + 自己
			tempResult += sampPointNums + 1;

			result = max(result, tempResult);
		}
		return result;
	}
};

你可能感兴趣的:(ACM算法实战--数学问题,LeetCode,字符串)