title

Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.

Example 1:

Input: [[1,1],[2,2],[3,3]]
Output: 3
Explanation:
^
|
|        o
|     o
|  o  
+------------->
0  1  2  3  4
Example 2:

Input: [[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]]
Output: 4
Explanation:
^
|
|  o
|     o        o
|        o
|  o        o
+------------------->
0  1  2  3  4  5  6

Analyze

  • 需要考虑的条件
    • points 中的值是否会重合?
    • 针对除不尽的数字, 精度问题是否需要考虑?
    • 传入参数个数;
  • 为避免除法带来的问题, 可以求最大公约数, 将 9/6, 18/12 转化为 3/2;
    • 在同一排可以表示为 '0/x', 在同一列可以表示为 'y/0';
    • 重合的点可以表示为 '0/0', 并用变量 samePoint 来记录它;

求最大公约数用到了数学中的辗转相除法: 两个正整数 a 和 b(a>b), 它们的最大公约数等于 a 除以 b 的余数 c 和 b 之间的最大公约数。比如 25 和 10, 25 除以 10 商 2 余 5, 那么 25 和 10 的最大公约数, 等同于 10 和 5 的最大公约数。

/**
 * @param {number[][]} points
 * @return {number}
 */
var maxPoints = function(points) {
  if (points.length === 0) return 0
  if (points.length === 1) return 1
  const getFractions = (pointsdiffX, pointsdiffY) => {
    if (pointsdiffX === 0 && pointsdiffY !== 0) return `y/0`
    if (pointsdiffX !== 0 && pointsdiffY === 0) return `0/x`
    if (pointsdiffX === 0 && pointsdiffY === 0) return `0/0`
    const gcdValue = gcd(pointsdiffY, pointsdiffX)
    const numerator = pointsdiffY / gcdValue
    const denominator = pointsdiffX / gcdValue
    return `${numerator}/${denominator}`
  }

  const gcd = (a, b) => {
    if (b === 0) {
      return a
    }
    return gcd(b, a % b)
  }

  let result = 0

  for (let m = 0; m < points.length; m++) {
    const map = new Map()
    let samePoint = 0
    for (let n = 0; n < points.length; n++) {
      if (m !== n) {
        const pointsdiffX = points[n][0] - points[m][0]
        const pointsdiffY = points[n][1] - points[m][1]
        if (pointsdiffX === 0 && pointsdiffY === 0) {
          samePoint++
        }
        const fractions = getFractions(pointsdiffX, pointsdiffY)
        if (map.has(fractions)) {
          map.set(fractions, map.get(fractions) + 1)
        } else {
          map.set(fractions, 1)
        }
      }
    }
    map.forEach((value, key) => {
      if (key !== '0/0') {
        result = Math.max(result, value + samePoint + 1)
      } else {
        result = Math.max(result, value + 1)
      }
    })
  }

  return result
}

Sister Title

149