`

Leetcode - Max Points on a Line

 
阅读更多
[分析]
两条直线若包含一个公共点且斜率相同,则为同一条直线。因此依次将数组中各点设为公共点,并计算所有未当过公共点的其他点同当当前公共点形成直线的斜率,使用哈希表保存各斜率直线上的点数,遍历过程中同时更新维护一条直线上包含的最多点数。
实现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;
    }
}
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics