149.直线上最多的点数

122 阅读1分钟

题目:
给你一个数组 points ,其中 points[i] = [xi, yi] 表示 X-Y 平面上的一个点。求最多有多少个点在同一条直线上。
解法:
方法一:错误,浮点数精度不够可能无法表述斜率。斜率保存到hash表中,注意int的除法会导致1/2 == 1/3,需要转换成浮点数。 整数的除法要考虑需不需要小鼠,要考虑小数取整的问题。

import "math"

func maxPoints(points [][]int) int {
	maxLines := 0
	for i := range points {
		rateCountMap := make(map[float64]int)
		for j := range points {
			if i == j {
				continue
			}
			lineRate := rate(points[i], points[j])
			rateCountMap[lineRate]++
			if rateCountMap[lineRate] > maxLines {
				maxLines = rateCountMap[lineRate]
			}
		}
	}
	return maxLines + 1
}

func rate(a, b []int) float64 {
	if a[0] == b[0] {
		return math.MaxInt32
	}else if a[0] > b[0] {
		return float64(a[1] - b[1]) / float64(a[0] - b[0])
	}
	return float64(b[1] - a[1]) / float64(b[0] - a[0])
}

方法二:斜率表示法 或者考虑对Δx/Δy取约分,即 2/4约分为1/2

func maxPoints(points [][]int) int {
	maxLines := 0
	for i := range points {
		rateCountMap := make(map[string]int)
		for j := range points {
			if i == j {
				continue
			}
			deltaX, deltaY := delta(points[i], points[j] )
                        // 没有相同的点保证了deltaX, deltaY不会同时为0,所以gcd总能获取到非0的那个数
			c := gcd(deltaX, deltaY)
			lineRate := fmt.Sprintf("%d-%d", deltaY / c , deltaX / c)
			rateCountMap[lineRate]++
			if rateCountMap[lineRate] > maxLines {
				maxLines = rateCountMap[lineRate]
			}
		}
	}
	return maxLines + 1
}

func delta(a, b []int) (int, int) {
	if a[0] > b[0] {
		return a[0] - b[0], a[1] - b[1] 
	}
	return b[0] - a[0], b[1] - a[1]
}
// 求a,b的最大公约数
func gcd(a, b int) int {
	if b == 0 {
		return a
	}
	return gcd(b, a % b)
}