两条直线若包含一个公共点且斜率相同,则为同一条直线。因此依次将数组中各点设为公共点,并计算所有未当过公共点的其他点同当当前公共点形成直线的斜率,使用哈希表保存各斜率直线上的点数,遍历过程中同时更新维护一条直线上包含的最多点数。
实现1中key直接就是double类型的斜率,实现时有几个注意点:
1)斜率为0时要单独判断并显式赋值为0,double类型0 和 -0是不等的
2)需要考虑输入中可能存在重复点
3)map,same, max为什么要放在循环里头定义?为什么需要max 和ret两个变量?因为它们统计的是以points[i]为公共点时数据,max可以看做时局部最大值,ret是全局最大值,不可混淆
实现2中key是斜率计算分式化简后的结果,避免使用double实际计算出斜率,参考
https://leetcode.com/discuss/9011/c-o-n-2-solution-for-your-reference
PS: leetcode 允许加打印语句进行调试啦~
/** * Definition for a point. * class Point { * int x; * int y; * Point() { x = 0; y = 0; } * Point(int a, int b) { x = a; y = b; } * } */ public class Solution { // Method 2 public int maxPoints(Point[] points) { if (points == null) return 0; if (points.length < 3) return points.length; int globalMax = 2; int N = points.length; for (int i = 0; i < N - 2; i++) { HashMap<String, Integer> map = new HashMap<String, Integer>(); int same = 0; int localMax = 1; //attention, not init to 0 int x1 = points[i].x, y1 = points[i].y; for (int j = i + 1; j < N; j++) { int x2 = points[j].x, y2 = points[j].y; int deltaX = x2 - x1; int deltaY = y2 - y1; int gcd = gcd(deltaX, deltaY); if (gcd == 0) { same++; continue; } deltaX /= gcd; deltaY /= gcd; String slope = deltaY + "/" + deltaX; if (map.containsKey(slope)) map.put(slope, map.get(slope) + 1); else map.put(slope, 2); localMax = Math.max(localMax, map.get(slope)); } globalMax = Math.max(globalMax, localMax + same); } return globalMax; } public int gcd(int a, int b) { return b != 0 ? gcd(b, a % b) : a; } // Method 1 public int maxPoints1(Point[] points) { if (points == null) return 0; if (points.length < 3) return points.length; int ret = 0; int N = points.length; for (int i = 0; i < N; i++) { HashMap<Double, Integer> map = new HashMap<Double, Integer>(); long x1 = points[i].x, y1 = points[i].y; int same = 0; int max = 1; for (int j = i + 1; j < N; j++) { long x2 = points[j].x, y2 = points[j].y; if (x1 == x2 && y1 == y2) {// specail attention same++; } else if (x1 == x2) { if (map.containsKey(Double.MAX_VALUE)) map.put(Double.MAX_VALUE, map.get(Double.MAX_VALUE) + 1); else map.put(Double.MAX_VALUE, 2); max = Math.max(max, map.get(Double.MAX_VALUE)); } else { double slope = 0; if (y1 == y2) slope = 0; // special attention, consider case[2, 3], [3, 3], [-5, 3] else slope = 1.0 * (y2 - y1) / (x2 - x1);; if (map.containsKey(slope)) map.put(slope, map.get(slope) + 1); else map.put(slope, 2); max = Math.max(max, map.get(slope)); } } // System.out.println(max + " " + same); ret = Math.max(ret, max + same); } return ret; } }