缀点成线[巧用变量抽象问题->统一操作]

验证所有点是否在一条直线上

前言

验证所有点在一条直线上,只需确定y=kx + b的k与b即可,但是k可能是无穷大,即直线垂直的时候。将函数抽象为x=0*y + b,这样还不够抽象,将x/y都视为一个变量时,两种情况对调传递变量即可统一操作。

一、案例

在这里插入图片描述

二、题解

step1. 通过两点确定抽象函数的k 与 b
step2.分情况传递对调参数,如何对调?可以通过给出起点start+step为正一负一控制。

class Solution {
    // 两个点确定一条直线。
    // 先确定直线,再验证其他点。
    // 直线看斜率,斜率分两种,[0,+∞) & x = b
    // x/y都是变量,统一成函数即可。
    public boolean checkStraightLine(int[][] coordinates) {
        int x1 = coordinates[0][0],y1 = coordinates[0][1];
        int x2 = coordinates[1][0],y2 = coordinates[1][1];
        // 情况1:无穷斜率
        if(x1 == x2) return isStraightLine(coordinates,0,x1,1,-1);
        // 情况2:y = kx + b
        double k = (y2 - y1) * 1.0 / (x2 - x1);
        return isStraightLine(coordinates,k,y1 - k * x1,0,1);
    }
    // 巧设变量值,将无穷斜率和正常斜率操作统一起来。
    public boolean isStraightLine(int[][] coordinates,double k,double b,int start,int step){
        for(int[] c : coordinates){
            if(c[start] * k + b != c[start + step]) return false;
        }
        return true;
    }
}
// y = kx + b || x = c
// 两点确定k&b,将上面两个函数抽象成:变量1 = k * 变量2 + b,用一个函数统一处理。
func checkStraightLine(coordinates [][]int) bool {
    // 给出两点
    x1,y1 := coordinates[0][0],coordinates[0][1]
    x2,y2 := coordinates[1][0],coordinates[1][1]
    // 情况1:x = 0 * y + b
    if x1 == x2 {
        return isStraightLine(coordinates,0,float64(x1),1,-1) // start = 1;step = -1来控制x/y的取值
    }
    // 情况2:y = k * x + b
    k := float64(y2 - y1) / float64(x2 - x1)
    return isStraightLine(coordinates,k,float64(y1) - k*float64(x1),0,1)
}
// 巧用变量start|step来抽象统一所有斜率的操作
func isStraightLine(coordinates [][]int,k,b float64,start,step int) bool {
    for _,c := range coordinates {
        // 验证y = kx + b
        if float64(c[start]) * k + b != float64(c[start + step]) {
            return false
        }
    }
    return true
}

总结

1)通过抽象问题,将问题视为一个模型,采用函数处理,做到复用简洁。
2)积累一些巧妙的方法,比如step为正一负一来控制走向,start来控制起点;除此之外,像idx++ & 1这种不断在0-1之间循环也比较常用。

参考文献

[1] LeetCode 缀点成线

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值