题目:
给你一个数组 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)
}