力扣:16.14. 最佳直线

257 阅读1分钟

「这是我参与11月更文挑战的第21天,活动详情查看:2021最后一次更文挑战

描述

给定一个二维平面及平面上的 N 个点列表Points,其中第i个点的坐标为Points[i]=[Xi,Yi]。请找出一条直线,其通过的点的数目最多。

设穿过最多点的直线所穿过的全部点编号从小到大排序的列表为S,你仅需返回[S[0],S[1]]作为答案,若有多条直线穿过了相同数量的点,则选择S[0]值较小的直线返回,S[0]相同则选择S[1]值较小的直线返回。

  • 示例 1:
输入: [[0,0],[1,1],[1,0],[2,0]]
输出: [0,2]
解释: 所求直线穿过的3个点的编号为[0,2,3]
  • 提示:
  • 2 <= len(Points) <= 300
  • len(Points[i]) = 2

解析

解答本题的思路比较笨重,还没有想到其他好的方式

  1. 两个点为一条直线, 遍历
  2. 组成的结果放在一个int[]里面
  3. 组合好了之后选一个最大的, 最大的里面选一个S[0,1]最小的
class Solution {
    public int[] bestLine(int[][] points) {
        // 思路:
        // 
​
        int[] remove = new int[points.length];
        int[][] max = new int[points.length][points.length];
        int maxNum = -1;
        for (int i = 0; i < points.length - 1; i ++) {
            for (int j = i + 1; j < points.length; j ++) {
                // 如果之前记录过这个点就跳过, 这个不应该, 如果这两个点在其他的线上
                // if (remove[j] == remove) {
                //     continue;
                // }
                // 计算直线公式
                double a, b, c;
                if (points[i][0] == points[j][0]) {
                    // x = c 类型
                    a = 1;
                    b = 0;
                    c = - points[i][0];
                } else {
                    // 运算要转double
                    a = ((double)(points[i][1] - points[j][1])) / (points[i][0] - points[j][0]);
                    c = points[i][1] - a * points[i][0];
                    b = -1;
                }
                // 遍历以后的每一个节点, 看是否符合
                int num = 2;
                for (int k = j + 1; k < points.length; k ++) {
                    // 加一个误差范围吧
                    if (-0.0001 < a * points[k][0] + b * points[k][1] + c && 0.0001 > a * points[k][0] + b * points[k][1] + c ) {
                        num ++;
                        // 记下这个点所在的线段
                        remove[k] = i + 1;
                    }
                }
                // 记录
                max[i][j] = num;
                maxNum = Math.max(num, maxNum);
            }
        }
​
        // 找到那个最大的
        for (int i = 0; i < points.length-1; i ++) {
            for (int j = i; j < points.length-1; j ++) {
                if (max[i][j] == maxNum) {
                    return new int[]{i, j};
                }
            }
        }
        return new int[]{-1, -1};
    }
}

运行结果:

执行结果:通过

执行用时:

内存消耗: