【Leetcode】1232. Check If It Is a Straight Line

题目地址:

https://leetcode.com/problems/check-if-it-is-a-straight-line/

给定平面坐标系 n n n个点的数组 A A A,即 A [ i ] A[i] A[i]代表平面中的点,问它们是否能确定一条直线。

可以以 A [ 0 ] A[0] A[0]为原点,看别的点与 A [ 0 ] A[0] A[0]之间直线的斜率。我们以一个数对 ( n , m ) (n,m) (n,m)表示斜率(真正的斜率实际上是 n m \frac{n}{m} mn),对斜率进行标准化,如果 m = 0 m=0 m=0那么令 n = + ∞ n=+\infty n=+,否则的话要求 m m m n n n互素并且 n n n非负(如果 n = 0 n=0 n=0则要求 m m m非负),具体做法是将它们除以最大公约数,然后保证 n n n非负。具体算法里,我们需要先找到第一个与 A [ 0 ] A[0] A[0]不同的点,这样才能确定直线的斜率 k k k,接下来再遇到别的点的时候只需要判断那个点与 A [ 0 ] A[0] A[0]的斜率也等于 k k k即可。代码如下:

import java.util.Arrays;
import java.util.Objects;

public class Solution {
    
    
    
    class Slope {
    
    
        // n / m
        int n, m;
        
        public Slope(int x, int y) {
    
    
        	// 斜率是无穷大,标准化之后n是正无穷,m是0
            if (y == 0) {
    
    
                n = Integer.MAX_VALUE;
                return;
            }
            
            n = x;
            m = y;
            // 否则先让n和m互素
            int gcd = gcd(n, m);
            n /= gcd;
            m /= gcd;
            
            // 如果n是0,则让m非负;如果n是负,则让n变为正
            if (n == 0) {
    
    
                m = Math.abs(m);
            } else if (n < 0) {
    
    
                n = -n;
                m = -m;
            }
        }
        
        private int gcd(int x, int y) {
    
    
            if (y == 0) {
    
    
                return Math.abs(x);
            }
            
            while (y != 0) {
    
    
                int tmp = y;
                y = x % y;
                x = tmp;
            }
            
            return x;
        }
        
        @Override
        public boolean equals(Object o) {
    
    
            Slope slope = (Slope) o;
            return n == slope.n && m == slope.m;
        }
        
        @Override
        public int hashCode() {
    
    
            return Objects.hash(n, m);
        }
    }
    
    public boolean checkStraightLine(int[][] coordinates) {
    
    
        Slope slope = null;
        for (int i = 1; i < coordinates.length; i++) {
    
    
        	// 略过与coordinates[0]相同的点
            if (Arrays.equals(coordinates[0], coordinates[i])) {
    
    
                continue;
            }
            
            // 遇到不同的点了,则可以确定一个斜率
            Slope curSlope = new Slope(coordinates[i][1] - coordinates[0][1], coordinates[i][0] - coordinates[0][0]);
            // 如果是第一次遇到不同的点,则可以确定直线的斜率;否则判断一下当前点与之前确定的斜率是否吻合
            if (slope == null) {
    
    
                slope = curSlope;
            } else if (!slope.equals(curSlope)) {
    
    
                return false;
            }
        }
    
    	// 如果走到这儿slope是null,则说明所有点都重合,此时不能确定一条直线,所以返回false;否则返回true
        return slope != null;
    }
}

时间复杂度 O ( n ) O(n) O(n),空间 O ( 1 ) O(1) O(1)

猜你喜欢

转载自blog.csdn.net/qq_46105170/article/details/112598561