LeetCode | 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.

分析

这题没什么巧妙解法,就是枚举。遍历每一个点,统计其它点与该点构成直线的斜率相同的个数。

需要注意两点:

1. 重复出现的点要特殊处理。

2. 用float或double类型来计算斜率,虽然能通过LeetCode测试,但其实是错误的,浮点型存在精度丢失问题。为了保证精度,可以采用分数形式纪录斜率,为了保证斜率纪录结果的一致,利用最大公约数对斜率进行约分化为最简形式后保存即可,同时需要注意斜率的正、负、零等问题。

代码

import java.util.HashMap;
import java.util.Map;

public class MaxPointsOnALine {
	class Point {
		int x;
		int y;

		Point() {
			x = 0;
			y = 0;
		}

		Point(int a, int b) {
			x = a;
			y = b;
		}
	}

	private int gcd(int a, int b) {
		return b > 0 ? gcd(b, a % b) : a;
	}

	public int maxPoints(Point[] points) {
		int ret = 0;

		if (points == null) {
			return 0;
		}

		int N = points.length;
		if (N <= 2) {
			return N;
		}

		Map<String, Integer> records = new HashMap<String, Integer>();
		for (int i = 0; i < N - 1; ++i) {
			int same = 1;
			int max = 0;
			records.clear();
			for (int j = i + 1; j < N; ++j) {
				// keep x not negative
				int x, y = 0;
				if (points[i].x >= points[j].x) {
					x = points[i].x - points[j].x;
					y = points[i].y - points[j].y;
				} else {
					x = points[j].x - points[i].x;
					y = points[j].y - points[i].y;
				}

				int gcdXY = gcd(Math.abs(x), Math.abs(y));
				if (gcdXY == 0) {
					// both x and y are zero
					// imply that points[i] and points[j] are equal
					++same;
				} else {
					x /= gcdXY;
					y /= gcdXY;
					// record
					if (x == 0 || y == 0) {
						x = Math.abs(x);
						y = Math.abs(y);
					}
					String key = x + ":" + y;
					int value = 0;
					if (records.containsKey(key)) {
						value = records.get(key);
					}
					records.put(key, ++value);
					max = Math.max(max, value);
				}
			}
			ret = Math.max(ret, max + same);
		}
		return ret;
	}
}



LeetCode | Max Points on a Line

上一篇:HDU 2296 ac自动机+dp


下一篇:NSURLSession学习笔记(二)Session Task