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
NOTE: input types have been changed on April 15, 2019. Please reset to default code definition to get new method signature.
题意:
给定二维平面上一些点,问最多多少个点共线
Solution1: HashMap
解本题需要的背景知识:【Math Fact】All the points in a line share the same slop.
The question is like standing at points[i], find max number of points in points[j], such that points[i] and points[j] are on the same line.
1. If points[i], points[j] 's coordinator are the same, they are overlapping.
2. Otherwise, they are nonoverlapping. Based on the fact that "All the points in a line share the same slop", we use the greatest common divisor(最大公约数) to get the lowest term(最简化) for points[i], points[j]'s coordinator. 即[2,4] 和[4,8], 我们用求最大公约数的方式,将其斜率化成最简形式: 1/2 和 1/2
3. We use Map<x, Map<y, occurance>> map to get such slop from x and y's occurance. Then we know how many non-overlapping points in such line.
code
1 public class MaxPointsonaLine { 2 // 已经给定的Point class 3 class Point { 4 int x; 5 int y; 6 7 Point() { 8 x = 0; 9 y = 0; 10 } 11 12 Point(int a, int b) { 13 x = a; 14 y = b; 15 } 16 } 17 18 public int maxPoints(Point[] points) { 19 int result = 0; 20 Map<Integer, Map<Integer, Integer>> map = new HashMap<>(); 21 // standing at points[i] 22 for (int i = 0; i < points.length; i++) { 23 map.clear(); 24 int overlapping = 0; 25 int nonoverlapping = 0; 26 // checking points[j] 27 for (int j = i + 1; j < points.length; j++) { 28 int x = points[j].x - points[i].x; 29 int y = points[j].y - points[i].y; 30 if (x == 0 && y == 0) { 31 overlapping++; 32 continue; 33 } 34 int gcd = generateGCD(x, y); 35 if (gcd != 0) { 36 x = x / gcd; 37 y = y / gcd; 38 } 39 if (map.containsKey(x)) { 40 if (map.get(x).containsKey(y)) { 41 map.get(x).put(y, map.get(x).get(y) + 1); 42 } else { 43 map.get(x).put(y, 1); 44 } 45 } else { 46 Map<Integer, Integer> m = new HashMap<>(); 47 m.put(y, 1); 48 map.put(x, m); 49 } 50 overlapping = Math.max(nonoverlapping, map.get(x).get(y)); 51 } 52 result = Math.max(result, overlapping + nonoverlapping + 1); 53 } 54 return result; 55 } 56 57 public int generateGCD(int a, int b) { 58 return (b == 0) ? a : generateGCD(b, a % b); 59 } 60 }