[LeetCode] Max Points on a Line

简介: This problem has a naive idea, which is to traverse all possible pairs of two points and see how many other points fall in the line determined by them.

This problem has a naive idea, which is to traverse all possible pairs of two points and see how many other points fall in the line determined by them. This idea is of O(n^3) time complexity and will meet TLE.

Well, let's focus on lines instead of pairs of points. Could we just find out how many points fall in all possible lines? The answer is yes. Remember that a line is determined by its slope and intercept. In fact, if two lines with the same slope share a common point, then they are just the same line. So to determine a line, we need its slope and a point.

Now comes the idea to solve this problem. We start from a specific point p, and compute all the slopes of the lines between p and the remaining points. Then those with the same slopes will be the same line. We can find out the maximum number of points fall on a line containing p. We exhaust all possible p's and record the largest number we have seen. This number is just answer.

Well, there are still two special cases to handle:

  1. Duplicate points: a pair of duplicate points give no determined line, so we just count the number of duplicates and add them to the result.
  2. Vertical lines: the slope of these lines is infinity mathematically. We simply set it to beINT_MAX in the following code.

Now we have the following code, using an unordered_map<float, int> slopes to record how many points fall in the line of a specific slope and containing points[i]. Since all the operations of unordered_map is O(1), this code is of O(n^2) complexity.

 1 class Solution {
 2 public:
 3     int maxPoints(vector<Point>& points) {
 4         unordered_map<float, int> slopes;
 5         int maxp = 0, n = points.size();
 6         for (int i = 0; i < n; i++) {
 7             slopes.clear();
 8             int duplicate = 1;
 9             for (int j = i + 1; j < n; j++) {
10                 if (points[j].x == points[i].x && points[j].y == points[i].y) {
11                     duplicate++;
12                     continue;
13                 }
14                 float slope = (points[j].x == points[i].x) ? INT_MAX : 
15                               (float)(points[j].y - points[i].y) / (points[j].x - points[i].x);
16                 slopes[slope]++;
17             }
18             maxp = max(maxp, duplicate);
19             for (auto slope : slopes)
20                 if (slope.second + duplicate > maxp) 
21                     maxp = slope.second + duplicate; 
22         }
23         return maxp;
24     }
25 };

Well, since the representation of floating point numbers is sometimes inaccurate, we may use a more safer way to represent the slope (dy / dx), which is to record dx and dy in a pair<int, int>. However, once we use pair<int, int> for the key of the map, we cannot use anunordered_map since pair<int, int> is unhashable. We now change to map and the time complexity becomes O(n^2logn). Also, since dy = 4, dx = 2 and dy = 8, dx = 4 represents the same slope, we need to divide both of them by their gcd first.

The code is as follows. The logic is the same of the one above, just introducing pair and gcd.

 1 class Solution { 
 2 public: 
 3     int maxPoints(vector<Point>& points) {
 4         map<pair<int, int>, int> slopes;
 5         int maxp = 0, n = points.size();
 6         for (int i = 0; i < n; i++) {
 7             slopes.clear();
 8             int duplicate = 1;
 9             for (int j = i + 1; j < n; j++) {
10                 if (points[j].x == points[i].x && points[j].y == points[i].y) {
11                     duplicate++;
12                     continue;
13                 }
14                 int dx = points[j].x - points[i].x;
15                 int dy = points[j].y - points[i].y;
16                 int dvs = gcd(dx, dy);
17                 slopes[make_pair(dx / dvs, dy / dvs)]++;
18             }
19             maxp = max(maxp, duplicate); 
20             for (auto slope : slopes)
21                 if (slope.second + duplicate > maxp)
22                     maxp = slope.second + duplicate;
23         } 
24         return maxp;
25     }
26 private:
27     int gcd(int num1, int num2) {
28         while (num2) {
29             int temp = num2; 
30             num2 = num1 % num2;
31             num1 = temp;
32         }
33         return num1;
34     }
35 };

 

目录
相关文章
|
算法
LeetCode 363. Max Sum of Rect No Larger Than K
给定一个非空二维矩阵 matrix 和一个整数 k,找到这个矩阵内部不大于 k 的最大矩形和。
105 0
LeetCode 363. Max Sum of Rect No Larger Than K
LeetCode 149. Max Points on a Line
给定一个二维平面,平面上有 n 个点,求最多有多少个点在同一条直线上。
109 0
LeetCode 149. Max Points on a Line
LeetCode之Max Consecutive Ones
LeetCode之Max Consecutive Ones
141 0
|
Java Python
LeetCode 485:连续最大1的个数 Max Consecutive Ones(python java)
公众号:爱写bug 给定一个二进制数组, 计算其中最大连续1的个数。 Given a binary array, find the maximum number of consecutive 1s in this array. 示例 1: 输入: [1,1,0,1,1,1] 输出: 3 解释: 开头的两位和最后的三位都是连续1,所以最大连续1的个数是 3. 注意: 输入的数组只包含 0 和1。
862 0
|
Java
[LeetCode]Max Area of Island 岛屿的最大面积
链接:https://leetcode.com/problems/max-area-of-island/description/难度:Easy题目:695.
880 0
|
4月前
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
5月前
|
Python
【Leetcode刷题Python】剑指 Offer 32 - III. 从上到下打印二叉树 III
本文介绍了两种Python实现方法,用于按照之字形顺序打印二叉树的层次遍历结果,实现了在奇数层正序、偶数层反序打印节点的功能。
69 6
|
5月前
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
137 2