[leetcode]149. Max Points on a Line@Java解题报告

https://leetcode.com/problems/max-points-on-a-line/description/




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


思路:这道题给了我们一堆二维点,然后让我们求最大的共线点的个数,根据初中数学我们知道,两点确定一条直线,而且可以写成y = ax + b的形式,所有共线的点都满足这个公式。

所以这些给定点两两之间都可以算一个斜率,每个斜率代表一条直线,对每一条直线,带入所有的点看是否共线并计算个数,这是整体的思路。但是还有两点特殊情况需要考虑:

一是当两个点重合时,无法确定一条直线,但这也是共线的情况,需要特殊处理。

二是斜率不存在的情况,由于两个点(x1, y1)和(x2, y2)的斜率k表示为(y2 - y1) / (x2 - x1),那么当x1 = x2时斜率不存在,这种共线情况需要特殊处理。

注意:还有一种情况需要特殊,用double表示斜率的时候会有误差,leetcode中有一个test是[[0,0],[94911151,94911150],[94911152,94911151]]

系统会把94911150/94911151和94911152/94911151当成同一个数。

因此,虽然解法二很容易理解,但是不是完美的解法

代码如下:

package go.jacob.day801;

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

public class Demo2 {
	/*
	 * 算法1 由于用double表示斜率会存在误差:详情参考算法二 该解法不适用斜率表示
	 */
	public int maxPoints(Point[] points) {
		if (points == null)
			return 0;
		if (points.length <= 2)
			return points.length;
		Map> map = new HashMap>();
		int res = 0;
		int max = 0;
		int overLap = 0;
		for (int i = 0; i < points.length - 1; i++) {
			//这里一定要清空map
			map.clear();
			overLap = 0;
			max = 0;
			for (int j = i + 1; j < points.length; j++) {
				int x = points[j].x - points[i].x;
				int y = points[j].y - points[i].y;
				if (x == 0 && y == 0) {
					overLap++;
					continue;
				}
				// 计算最大公约数:欧几里得算法
				// 因为用分数代替斜率,所以必须保证分子分母最简
				int gcd = generateGCD(x, y);
				if (gcd != 0) {
					x = x / gcd;
					y = y / gcd;
				}
				if (map.containsKey(x)) {
					if (map.get(x).containsKey(y))
						map.get(x).put(y, map.get(x).get(y) + 1);
					else
						map.get(x).put(y, 1);
				} else {
					Map temp = new HashMap();
					temp.put(y, 1);
					map.put(x, temp);
				}
				max = Math.max(max, map.get(x).get(y));
			}
			res = Math.max(res, max + overLap + 1);
		}

		return res;
	}

	// 欧几里得算法:计算最小公约数
	private int generateGCD(int x, int y) {
		if (y == 0)
			return x;
		return generateGCD(y, x % y);
	}

	/*
	 * 解法2:由于double的精度问题,无法通过全部测试
	 */
	public int maxPoints_2(Point[] points) {
		if (points.length <= 0)
			return 0;
		if (points.length <= 2)
			return points.length;
		int result = 0;
		for (int i = 0; i < points.length; i++) {
			HashMap hm = new HashMap();
			int samex = 1;
			int samep = 0;
			for (int j = 0; j < points.length; j++) {
				if (j != i) {
					if ((points[j].x == points[i].x) && (points[j].y == points[i].y)) {
						samep++;
					}
					if (points[j].x == points[i].x) {
						samex++;
						continue;
					}
					double k = (double) (points[j].y - points[i].y) / (double) (points[j].x - points[i].x);
					if (hm.containsKey(k)) {
						hm.put(k, hm.get(k) + 1);
					} else {
						hm.put(k, 2);
					}
					result = Math.max(result, hm.get(k) + samep);
				}
			}
			result = Math.max(result, samex);
		}
		return result;
	}

	private class Point {
		int x;
		int y;

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

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



你可能感兴趣的:(leetcode)