• [leetcode 周赛 159] 1232 缀点成线


    1232 Check If It Is a Straight Line 缀点成线

    问题描述

    在一个 XY 坐标系中有一些点,我们用数组 coordinates 来分别记录它们的坐标,其中 coordinates[i] = [x, y] 表示横坐标为 x、纵坐标为 y 的点。

    请你来判断,这些点是否在该坐标系中属于同一条直线上,是则返回 true,否则请返回 false

    示例 1:

    输入: coordinates = [[1,2],[2,3],[3,4],[4,5],[5,6],[6,7]]
    输出: true

    示例 2:

    输入: coordinates = [[1,1],[2,2],[3,4],[4,5],[5,6],[7,7]]
    输出: false

    提示:

    • 2 <= coordinates.length <= 1000
    • coordinates[i].length == 2
    • -10^4 <= coordinates[i][0], coordinates[i][1] <= 10^4
    • coordinates 中不含重复的点

    思路

    • 读题
      连点成线, 一条线上的点有什么特点? 斜率相等

    暴力法 因为点不多(1000以内)

    枚举这条线的状态: 斜的/平的/竖的

    • 平的: y值相等
    • 竖的: x值相等
    • 斜的: 斜率(y1-y2)/(x1-x2)相等

    公式法 y=kx+b

    通过两个点, 确定k, b的值, 建立直线公式y=kx+b
    将剩余点逐一代入公式

    代码实现

    暴力法

    class Solution {
        public boolean checkStraightLine(int[][] coordinates) {
            int len = coordinates.length;
            
            // x轴是否相等
            int linex = coordinates[0][0];
            boolean yes = true;
            for (int i = 1; i < len; i++) {
                if (coordinates[i][0] != linex) {
                    yes = false;
                    break;
                }
            }
            // 如果x值全相等 竖线
            if (yes) return true;
            
            // y轴是否相等
            int liney = coordinates[0][1];
            yes = true;
            for (int i = 1; i < len; i++) {
                if (coordinates[i][1] != liney) {
                    yes = false;
                    break;
                }
            }
            // 如果y值全相等 横线
            if (yes) return true;
            
            // 斜线
            int dx = coordinates[1][0]-coordinates[0][0], x1 = coordinates[0][0];
            int dy = coordinates[1][1]-coordinates[0][1], y1 = coordinates[0][1];
            if (dx == 0 || dy == 0) {
                return false;
            }
            // 初始斜率
            double dxy = dx/dy;
            for (int i = 2; i < len; i++) {
                int curx = coordinates[i][0], cury = coordinates[i][1];
                // 因为不可能出现斜率为0(竖线/横线)
                if ((curx-x1) == 0 || (cury-y1) == 0) {
                    return false;
                }
                // 当前点斜率
                double dcp = (curx-x1)/(cury-y1);
                if (dxy == dcp) {
                    continue;
                }
                return false;
            }
            
            return true;
        }
    }
    

    公式法

    class Solution {
        public boolean checkStraightLine(int[][] coordinates) {
            int len = coordinates.length;
            // 两点必定一线
            if (len <= 2) {
                return true;
            }
            
            int x1 = coordinates[0][0], y1 = coordinates[0][1];
            int x2 = coordinates[1][0], y2 = coordinates[1][1];
        
            // y = kx+b --> k = (y1-y2)/(x1-x2)  b = y-kx
            int k, b; 
            if (x1 == x2) {
                k = 0;
            } else {
                k = (y1-y2)/(x1-x2);
            }
            b = y1 - k*x1;
            
            for (int i = 3; i < len; i++) {
                int y = coordinates[i][1], x = coordinates[i][0];
                if (y != k*x + b) {
                    return false;
                }
            }
            
            return true;
        }
    }
    

    参考资源

    第 159 场力扣周赛 讨论区

  • 相关阅读:
    Netty回调与Channel执行流程分析
    Netty执行流程分析与重要组件介绍
    HBase 介绍
    Java文件上传下载原理
    ngxtop安装和使用
    开启Nginx监控 with-http_stub_status_module
    Spring 事务模板方法设计模式
    Spring 事务管理
    JdkDynamicAopProxy 拦截器链的获得与递归执行
    CgLib实现AOP
  • 原文地址:https://www.cnblogs.com/slowbirdoflsh/p/11779111.html
Copyright © 2020-2023  润新知