Easy题,一开始的思路是间接算斜率,然而除法应用了浮点数来计算斜率,这可能导致精度问题。只管这种状况在大多数理论利用中并不常见,但如果输出的坐标值十分大或十分小,那么就可能遇到精度问题。此外,因为浮点数的不精确性,即便两个斜率实际上是相等的,比拟也可能会返回false。另外这种办法还不能很好的解决水平线的问题,算进去inf,-inf须要做额定的判断
impl Solution { pub fn check_straight_line(coordinates: Vec<Vec<i32>>) -> bool { if coordinates.len() <= 2 { return true } let gradient = (coordinates[1][1] as f32 - coordinates[0][1] as f32) / (coordinates[1][0] as f32 - coordinates[0][0] as f32); for coordinate in coordinates.iter().skip(2){ let x = coordinate[0] as f32; let y = coordinate[1] as f32; println!("{}, {}", x, y); println!("gradient: {}", gradient); println!("gradient here: {}", (y - coordinates[0][1] as f32) / (x - coordinates[0][0] as f32)); if (y - coordinates[0][1] as f32) / (x - coordinates[0][0] as f32) != gradient { return false } } true }}
随后想到用乘法来防止找个问题。穿插乘法的斜率的核心思想基于这样一个事实:在二维立体上,两个点之间的斜率是一个常数。具体来说,对于点 (x1, y1) 和 (x2, y2),斜率 m 能够示意为:
m = (y2 - y1) / (x2 - x1)
咱们能够对这个等式进行穿插乘法,将除法变为乘法,失去:
m * (x2 - x1) = y2 - y1
这样,咱们就能够比拟两个斜率是否相等,而不须要执行除法。例如,对于另一个点 (x3, y3),咱们能够查看以下等式是否成立:
m * (x3 - x1) = y3 - y1
如果它们相等,那么这三个点在同一直线上。如果不等,那么这三个点不在同一直线上。咱们实际上只是在比拟两个差值的乘积是否相等。
这种办法的长处是防止了除法(特地是除以零的问题),并且应用了整数运算,防止了浮点数的精度问题。
impl Solution { pub fn check_straight_line(coordinates: Vec<Vec<i32>>) -> bool { if coordinates.len() <= 2 { return true } let (dx, dy) = ( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1] ); for i in 2..coordinates.len() { let (dx1, dy1) = ( coordinates[i][0] - coordinates[0][0], coordinates[i][1] - coordinates[0][1] ); if dx * dy1 != dy * dx1 { return false } } true }}