[LeetCode] Max Points on a Line 题解
题意
Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.
意思就是说在给定的节点中计算出在同一条直线上的最大节点个数。
思路
这道题,题意很容易理解,但是需要注意的东西包括,如果你用斜率计算,那么就需要注意到精确度的问题,否则就会变成相等的斜率,无奈之下,只能提高精确度,比如说用long double,但这不是持久的办法,目前的办法是使用最大公约数。
其实我大概的思路已经想到了,就是第五种方法的思路,这道题没做出来的原因是,没有考虑到相同点以及相同的x的情况。
代码
#include <stdio.h>
#include <stdio.h>
#include <string>
#include <vector>
#include <iostream>
#include <unordered_map>
#include <map>
#include <set>
using namespace std;
/**
* Definition for a point.
*/
struct Point {
int x;
int y;
Point() : x(0), y(0) {}
Point(int a, int b) : x(a), y(b) {}
};
/**
* 第一种方法:将每一个顶点和其他的顶点进行计算得出斜率,
* 用hash保存下来,key为斜率,value为总个数
* 因为相同斜率的则在同一条线上
*
* @param points <#points description#>
*
* @return <#return value description#>
*/
int maxPoints(vector<Point>& points) {
unordered_map<int, int> hash;
int maxCnt = 0;
auto caculateK = [&](Point p1, Point p2) {
int k = (p2.y - p1.y)/(p2.x - p1.x);
return k;
};
for (int i = 0; i < points.size(); i++) {
Point pointA = points[i];
for (int j = 0; j < points.size() && i != j; j++) {
Point pointB = points[j];
int k = caculateK(pointA, pointB);
if (hash.find(k) != hash.end()) {
hash[k]++;
}
else {
hash.insert(make_pair(k, 1));
}
}
// hash.clear();
}
for (auto itr = hash.begin(); itr != hash.end(); itr++) {
maxCnt = std::max((*itr).second, maxCnt);
}
return maxCnt + 2;
}
/**
* 计算最大公约数
*/
int GCD(int a, int b) {
if(b==0) return a;
else return GCD(b, a%b);
}
/**
* 这个方法不再是使用斜率作为map的key,而是使用的是gcd(最大公约数)
* 总之结果就是overlap+localmax+vertical+1,
* 其中overlap代表的是完全相同的顶点,vertical代表的是只有x是相等的,因为相减会导致0
*
* @param points <#points description#>
*
* @return <#return value description#>
*/
int maxPoints2(vector<Point>& points) {
if (points.size() < 2) {
return (int)points.size();
}
int result = 0;
for (int i = 0; i < points.size(); i++) {
map<pair<int, int>, int> lines;
int localmax = 0, overlap = 0, vertical = 0;
for (int j = i+1; j < points.size(); j++) {
// 相同的点的个数
if (points[j].x == points[i].x && points[j].y == points[i].y) {
overlap++;
continue;
}
else if (points[j].x == points[i].x) {
vertical++;
}
else {
int a=points[j].x-points[i].x, b=points[j].y-points[i].y;
int gcd=GCD(a, b);
a/=gcd;
b/=gcd;
lines[make_pair(a, b)]++;
localmax=std::max(lines[make_pair(a, b)], localmax);
}
localmax=std::max(vertical, localmax);
}
// 结果为
result = std::max(result, localmax+overlap+1); //这里加一是因为之前vertical只计算了一次
}
return result;
}
// 由于精确度问题,更改double
inline bool double_equal(double a, double b) { return abs(a-b) < 1e-10; }
inline bool double_less (double a, double b) { return a-b < -1e-10; }
struct Line {
double r; // ratio ; slope
double t; // translation
Line(Point p, Point q) { // math
if (q.x == p.x) r = 1e20, t = p.x;
else
{
r = (double) (q.y-p.y) / (double) (q.x-p.x);
t = p.y - p.x * r;
}
}
};
// 用作排序
bool operator < (const Line& a, const Line& b) {
return a.r == b.r ? a.t < b.t : a.r < b.r;
}
// 依此来判断map中是否相等
bool operator == (const Line& a, const Line& b) {
return a.r == b.r && a.t == b.t;
}
/**
* 这个思路最大的特点就是利用了一个结构体和set的原理
* 因为set可以自动去除掉重复的元素
*
* @param points <#points description#>
*
* @return <#return value description#>
*/
int maxPoints4(vector<Point> &points) {
if (points.empty()) return 0;
map<Line, set<Point*> > line_map;
for (auto & a : points)
for (auto & b : points)
{
Line line(a,b);
line_map[line].insert(&a);
line_map[line].insert(&b);
}
int ret = 1;
for (auto & pr : line_map) ret = max(ret,(int)pr.second.size());
return ret;
}
/**
* 最直接最简单的做法
*
* @param points <#points description#>
*
* @return <#return value description#>
*/
int maxPoints5(vector<Point>& points) {
if(points.empty())
return 0;
else if(points.size() == 1)
return 1;
int ret = 0;
for(int i = 0; i < points.size(); i ++)
{//start point
int curmax = 1; //points[i] itself
unordered_map<long double, int> kcnt; // slope_k count
int vcnt = 0; // vertical count
int dup = 0; // duplicate added to curmax
for(int j = 0; j < points.size(); j ++)
{
if(j != i)
{
long double deltax = points[i].x - points[j].x;
long double deltay = points[i].y - points[j].y;
if(deltax == 0 && deltay == 0) {
dup ++;
}
else if(deltax == 0)
{
if(vcnt == 0)
vcnt = 2;
else
vcnt ++;
curmax = max(curmax, vcnt);
}
else
{
long double k = deltay / deltax;
if(kcnt[k] == 0)
kcnt[k] = 2;
else
kcnt[k] ++;
curmax = max(curmax, kcnt[k]);
}
}
}
ret = max(ret, curmax + dup);
}
return ret;
}
int main(int argc, const char * argv[]) {
vector<Point> points;
Point point1(0, 0), point2(94911151, 94911150), point3(94911152, 94911151), point4(5, 6);
points.push_back(point1);
points.push_back(point2);
points.push_back(point3);
int result = maxPoints5(points);
cout << "result..." << result << endl;
return 0;
}
[LeetCode] Max Points on a Line 题解的更多相关文章
- LeetCode: Max Points on a Line 解题报告
Max Points on a Line Given n points on a 2D plane, find the maximum number of points that lie on the ...
- [LeetCode] Max Points on a Line 共线点个数
Given n points on a 2D plane, find the maximum number of points that lie on the same straight line. ...
- [leetcode]Max Points on a Line @ Python
原题地址:https://oj.leetcode.com/problems/max-points-on-a-line/ 题意:Given n points on a 2D plane, find th ...
- LeetCode:Max Points on a Line
题目链接 Given n points on a 2D plane, find the maximum number of points that lie on the same straight l ...
- 【leetcode】Max Points on a Line
Max Points on a Line 题目描述: Given n points on a 2D plane, find the maximum number of points that lie ...
- [LeetCode OJ] Max Points on a Line
Max Points on a Line Submission Details 27 / 27 test cases passed. Status: Accepted Runtime: 472 ms ...
- 【LeetCode】149. Max Points on a Line
Max Points on a Line Given n points on a 2D plane, find the maximum number of points that lie on the ...
- [LintCode] Max Points on a Line 共线点个数
Given n points on a 2D plane, find the maximum number of points that lie on the same straight line. ...
- Max Points on a Line leetcode java
题目: Given n points on a 2D plane, find the maximum number of points that lie on the same straight li ...
随机推荐
- 推荐一本springBoot学习书籍---深入浅出springBoot2.x
花了几周时间读完了这本书,确实是一本特别详细全面的书,而且不单单只是springBoot, 书中还介绍了许多工作中常用的技术与springBoot的整合使用,当然,也有一些小bug, 因为在代码实践过 ...
- 【FCS NOI2018】福建省冬摸鱼笔记 day4
第四天. 动态规划专题,讲师:闫神 讲了一些DP优化技巧,然而思想难度好大啊……根本没想到能优化那地步,连DP方程都没有呢. 不过有几题我还是想明白了. 讲了单调队列,决策单调性,四边形不等式,斜率优 ...
- Method for balancing binary search trees
Method for balancing a binary search tree. A computer implemented method for balancing a binary sear ...
- Using KernelShark to analyze the real-time scheduler【转】
转自:https://lwn.net/Articles/425583/ This article brought to you by LWN subscribers Subscribers to LW ...
- Linux中断处理驱动程序编写【转】
转自:http://blog.163.com/baosongliang@126/blog/static/1949357020132585316912/ 本章节我们一起来探讨一下Linux中的中断 中断 ...
- Java Http接口加签、验签操作方法
1.业务背景 最近接触了一些电商业务,发现在处理电商业务接口时,比如淘宝.支付类接口,接口双方为了确保数据参数在传输过程中未经过篡改,都需要对接口数据进行加签,然后在接口服务器端对接口参数进行验签,确 ...
- Python学习笔记:个税起征点上调至5000,算一算少交多少税?
一.旧税率表与新税率表比较 以前起征点是3500,2018年10月1日起起征点正式修改为5000,下面我们用Python来分别计算新旧个人所得税分别为多少? 二.旧的个人所得税 import sys ...
- C# 文件存在,但是File.Exists 判断不存在的问题
这里说的不是文件路径错了的情况,而是明明文件就存在,但是File.Exists返回false. win10系统. 查看接口说明才知道,如果你不是按管理员方式启动VS,而此文件需要管理员权限才能访问,此 ...
- 一步一步学习IdentityServer3 (13) 令牌
IdentityServer3中客户端保护了授权资源,不难看出在IdentityServer3中,有这样一个设置 AllowedScopes = new List<string> { &q ...
- Hive(九)Hive 执行过程实例分析
一.Hive 执行过程概述 1.概述 (1) Hive 将 HQL 转换成一组操作符(Operator),比如 GroupByOperator, JoinOperator 等 (2)操作符 Opera ...