直线上最多的点数

149. 直线上最多的点数

题目: 给你一个数组 points ,其中 points[i] = [xi, yi] 表示 X-Y 平面上的一个点。求最多有多少个点在同一条直线上。

解法1:暴力求解

思路: 利用基准点和斜率(y1-y2/x1-x2),两层循环,每次将与基准点构成的不同斜率存在hash中,相同则计数,一趟下来求max。
注意点:需要区别y1-y2 === 0 和 x1-x2 === 0 的情况。

时间复杂度: O(n^2)
空间复杂度:O(n)

var maxPoints = function(points) {
    // 经过某点的斜率
    let max = 0;
    for(let i = 0; i < points.length; i++) {
        max === 0 ? max = 1 : null;
        const hash = {};
        for(let j = i+1; j < points.length; j++) {
            const k = points[i][0]-points[j][0] === 0 ? '+0' : (points[i][1]-points[j][1])/(points[i][0]-points[j][0]);
            hash[k] ? hash[k]++ : hash[k] = 2;
        };
        for(let i in hash) {
            max = Math.max(max, hash[i]);
        }
    }
    return max;
};

优化:

  1. 点的总数量小于等于 2 的情况下,我们总可以用一条直线将所有点串联,此时我们直接返回点的总数量即可;
  2. 当我们找到一条直线经过了图中超过半数的点时,我们即可以确定该直线即为经过最多点的直线;
  3. 当我们枚举到点 i(假设编号从 0 开始)时,我们至多只能找到 n−i 个点共线。假设此前找到的共线的点的数量的最大值为 k,如果有 k≥n−i,那么此时我们即可停止枚举,因为不可能再找到更大的答案了。

作者:LeetCode-Solution
链接:https://leetcode.cn/problems/max-points-on-a-line/solution/zhi-xian-shang-zui-duo-de-dian-shu-by-le-tq8f/

var maxPoints = function(points) {
    // 经过某点的斜率
    let max = 0;
    // 优化1
    if (points.length <= 2) return points.length;
    for(let i = 0; i < points.length; i++) {
    // 优化2
        if (max > Math.floor(points.length / 2) || max >= points.length - i) {
            break;
        }
        const hash = {};
        for(let j = i+1; j < points.length; j++) {
            const k = points[i][0]-points[j][0] === 0 ? '+0' : (points[i][1]-points[j][1])/(points[i][0]-points[j][0]);
            hash[k] ? hash[k]++ : hash[k] = 2;
        };
        for(let i in hash) {
            max = Math.max(max, hash[i]);
        }
    }
    return max;
};

学生方阵(huawei机试)

在这里插入图片描述

思路: 分别在各个方向上统计连续1的个数,取max。

时间复杂度O(n^m
m^n
2(Math(m, n)^n
Math(m,n)^m))

// 定义女:0, 男: 1
// 分类讨论
// 水平方向
var row = function (arr) {
    let max = 0;
    for(let i = 0; i < arr.length; i++) {
        let front, count = 0;
        for(let j = 0; j < arr[i].length; j++) {
            if (arr[i][j]) {
                count = front ? count + 1 : 1;
                front = 1;
            } else {
                front = 0;
            }
            max = Math.max(max, count);
        }
    }
    return max;
}
// 竖直方向
var column = function (arr) {
    let max = 0;
    for(let i = 0; i < arr[0].length; i++) {
        let front, count = 0;
        for(let j = 0; j < arr.length; j++) {
            if (arr[j][i]) {
                count = front ? count + 1 : 1;
                front = 1;
            } else {
                front = 0;
            }
            max = Math.max(max, count);
        }
    }
    return max;
}
// 对角线
var xie = function (arr) {
    let max = 0;
    // 下三角
    for(let l = 0; l < arr.length ; l++) {
        let front, count = 0;
        for(let i = l, j = 0; i < arr.length && j < arr[0].length; j++, i++) {
            if (arr[i][j]) {
                count = front ? count + 1 : 1;
                front = 1;
            } else {
                front = 0;
            }
            max = Math.max(max, count);
        }
    }
    // 上三角
    for(let l = 1; l < arr[0].length ; l++) {
        let front, count = 0;
        for(let i = 0, j = l; i < arr.length && j < arr[0].length; j++, i++) {
            if (arr[i][j]) {
                count = front ? count + 1 : 1;
                front = 1;
            } else {
                front = 0;
            }
            max = Math.max(max, count);
        }
    }
    return max;
}
var fanXie = function (arr) {
    let max = 0;
    // 上三角
    for(let l = 0; l < arr[0].length ; l++) {
        let front, count = 0;
        for(let i = 0, j = l; i < arr.length && j > -1; j--, i++) {
            if (arr[i][j]) {
                count = front ? count + 1 : 1;
                front = 1;
            } else {
                front = 0;
            }
            max = Math.max(max, count);
        }
    }
    // 下三角
    for(let l = 1; l < arr.length ; l++) {
        let front, count = 0;
        for(let i = l, j = arr[0].length - 1; i < arr.length && j > -1; j--, i++) {
            if (arr[i][j]) {
                count = front ? count + 1 : 1;
                front = 1;
            } else {
                front = 0;
            }
            max = Math.max(max, count);
        }
    }
    return max;
}
var getLianCount = function (arr) {
    let rowMax = row(arr);
    let colMax = column(arr);
    let xieMax = xie(arr);
    let fanXieMax = fanXie(arr);
    return Math.max(rowMax, colMax, xieMax, fanXieMax);
}

console.log(getLianCount([
    [1,0,0,1],
    [1,1,0,1],
    [1,1,1,0]
]))

329. 矩阵中的最长递增路径

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值