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

来源:互联网 发布:页游广告知乎 编辑:程序博客网 时间:2024/05/18 12:41

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<Integer, Map<Integer, Integer>> map = new HashMap<Integer, Map<Integer, Integer>>();int res = 0;int max = 0;int overLap = 0;for (int i = 0; i < points.length - 1; i++) {//这里一定要清空mapmap.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);elsemap.get(x).put(y, 1);} else {Map<Integer, Integer> temp = new HashMap<Integer, Integer>();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<Double, Integer> hm = new HashMap<Double, Integer>();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;}}}



原创粉丝点击