给定一个二维平面,平面上有 个点,求最多有多少个点在同一条直线上。

示例 1:

输入: [[1,1],[2,2],[3,3]]
输出: 3
解释:
^
|
|        o
|     o
|  o  
+------------->
0  1  2  3 4

示例 2:

输入: [[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]]
输出: 4
解释:
^
|
| o
|     o   o
|      o
|  o   o
+------------------->
0  1  2  3  4  5  6 看到此题,第一想法是用一个数据结构来表示某一条直线,直线的表达式有y = ax + b ,那提取出 a和b是不是就可以了,写完发现还有x = 1这种直线。然后想通过hashmap来保存直线对应的点数,如果参数a和b是个1/3这种值,由于精度问题,算出来的两个直线的数据结构的hash值就不一样,hashmap就是认为是两个key。 最后无奈换成分数表达式 y = (a1/a2)*x + b1/b2; b1/b2 = (a2*y - a1*x)/a2;这样4个int变量,就可以精确表示一条直线.当然,分数需要进行约分!
struct FPoint {
int a1;
int a2;
int b1;
int b2;
FPoint() : a1(), a2(), b1(), b2() {}
FPoint(int _a1, int _a2)
{
if (_a1 * _a2 > )
{
a1 = abs(_a1);
a2 = abs(_a2);
}
else
{
a1 = - * abs(_a1);
a2 = abs(_a2);
}
b1 = ;
b2 = ;
}
bool Contain(Point p)const
{
long long int t1 = 1L, t2 = 1L;
t1 = t1 * p.y * (a2*b2);
t2 = t2 * a1*b2*p.x + b1*a2;
return a2 == ? p.x == b1 / b2 : t1 == t2;
}
void Normal()
{
if (a1 == && a2 == )
{
}
else if (a1 == )
a2 = ;
else if (a2 == )
a1 = ;
else
{
int s = a1*a2 > ? : -;
a1 = abs(a1);
a2 = abs(a2);
int _gcd = GCD(a1, a2);
a1 = s * a1 / _gcd;
a2 = a2 / _gcd; if (b1 == )
b2 = ;
else
{
s = b1*b2 > ? : -;
b1 = abs(b1);
b2 = abs(b2);
_gcd = GCD(b1, b2);
b1 = s * b1 / _gcd;
b2 = b2 / _gcd;
}
} }
  //最大公约数
int GCD(int a, int b){
int m = a, n = b, r;
if (m < n){
int temp = m;
m = n;
n = temp;
}
r = m % n;
while (r){
m = n;
n = r;
r = m % n;
}
return n;
}
};
struct RecordHash
{
size_t operator()(const FPoint& f) const{
return hash<int>()(f.a1) ^ hash<int>()(f.a2) ^ hash<int>()(f.b1) ^ hash<int>()(f.b2);
}
};
struct RecordCmp
{
bool operator()(const FPoint& f1, const FPoint& f2) const{
return f1.a1 == f2.a1 && f1.a2 == f2.a2 &&f1.b1 == f2.b1&&f1.b2 == f2.b2;
}
}; class Solution {
public:
FPoint GetPoint(Point a, Point b)
{
FPoint f(b.y - a.y, b.x - a.x );
if (f.a2 == )
{
f.b1 = a.x;
f.b2 = ;
}
else
{
f.b1 = (f.a2*a.y - f.a1*a.x);
f.b2 = f.a2;
}
return f;
}
int maxPoints(vector<Point>& points) {
if (points.size() <= )
{
return points.size();
}
unordered_set<int> index_set;
unordered_map<FPoint, int, RecordHash, RecordCmp> line_map;
int max_point = ;
for (int i = ; i < points.size(); i++)
{
unordered_map<FPoint, int, RecordHash, RecordCmp>::iterator itr = line_map.begin();
for (; itr != line_map.end(); itr++)
{
if (itr->first.Contain(points[i]))
{
itr->second++;
max_point = max(max_point, itr->second);
if (index_set.count(i) == )index_set.insert(i);
}
}
for (int r = ; r < points.size() ; r++)
{
if (r != i && index_set.count(r) == )
{
FPoint f = GetPoint(points[i], points[r]);
f.Normal();
if (line_map[f] == )
{
line_map[f]++;
}
if (index_set.count(i) == )
{
index_set.insert(i);
}
max_point = max(max_point, line_map[f]);
}
}
}
return max_point;
}
};

Max Points on a Line(直线上最多的点数)的更多相关文章

  1. 149 Max Points on a Line 直线上最多的点数

    给定二维平面上有 n 个点,求最多有多少点在同一条直线上. 详见:https://leetcode.com/problems/max-points-on-a-line/description/ Jav ...

  2. Leetcode 149.直线上最多的点数

    直线上最多的点数 给定一个二维平面,平面上有 n 个点,求最多有多少个点在同一条直线上. 示例 1: 输入: [[1,1],[2,2],[3,3]] 输出: 3 解释: ^ | |        o ...

  3. Java实现 LeetCode 149 直线上最多的点数

    149. 直线上最多的点数 给定一个二维平面,平面上有 n 个点,求最多有多少个点在同一条直线上. 示例 1: 输入: [[1,1],[2,2],[3,3]] 输出: 3 解释: ^ | | o | ...

  4. [Swift]LeetCode149. 直线上最多的点数 | 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. ...

  5. leetcode 149. 直线上最多的点数 解题报告

    给定一个二维平面,平面上有 n 个点,求最多有多少个点在同一条直线上. 示例 1: 输入: [[1,1],[2,2],[3,3]] 输出: 3 解释: ^ | | o | o | o +------- ...

  6. 【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 ...

  7. [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 ...

  8. LeetCode之Max Points on a Line Total

    1.问题描述 Given n points on a 2D plane, find the maximum number of points that lie on the same straight ...

  9. BZOJ3403: [Usaco2009 Open]Cow Line 直线上的牛

    3403: [Usaco2009 Open]Cow Line 直线上的牛 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 48  Solved: 41[S ...

随机推荐

  1. webpack的热更新

    webpack的热更新是如何做到的?说明其原理? webpack的热更新又称热替换(Hot Module Replacement),缩写为HMR. 这个机制可以做到不用刷新浏览器而将新变更的模块替换掉 ...

  2. 高级函数-sign

    ==========sign函数介绍(补充)===========   sign(n):判断n>0返回1;n=0返回0;n<0返回-1.   select sign(10),sign(0) ...

  3. iBase4J部署总结

    iBase4J部署总结 序言 最近看到个分布式框架,只有一个字:好.所以部署起来看看.开始的时候说实话遇到了点困难.去码云上看了下,貌似想得到指导要加入一个群,而且需要收费的,反正闲来无事,索性自己搞 ...

  4. jquery-jquery异步提交表单插件

    使用jquery.form可以异步提交文件或者表单,下面的代码演示了如何提交文件 http://apps.bdimg.com/libs/jquery/2.1.1/jquery.min.js <s ...

  5. HDU 1040.As Easy As A+B【排序】【如题(水!水!水!)】【8月24】

    As Easy As A+B Problem Description These days, I am thinking about a question, how can I get a probl ...

  6. 剪切具有CornerRadius的RectangleGeometry(可能在Ripple中用到)

    剪切具有CornerRadius的RectangleGeometry(可能在Ripple中用到) 1.新建Converter public class BorderClipConverter : IM ...

  7. [jzoj NOIP2018模拟10.29]

    OI生涯的最高分,来了纪中这么多天,在经历了这么多场“NOIP难度”的模拟赛之后,终于看到了真正的NOIP 今天考场上效率很高,很快码完了全部的题目,留下了足够的时间对拍和...发呆.不得不说看着电脑 ...

  8. POJ 1945 暴搜+打表 (Or 暴搜+判重)

    思路: 呃呃 暴搜+打表 暴搜的程序::稳稳的TLE+MLE (但是我们可以用来打表) 然后我们就可以打表过了 hiahiahia 可以证明最小的那个数不会超过200(怎么证明的我也不知道),然后就直 ...

  9. ios上有时候提交按钮点击两次才可以取消输入框软键盘

    ios上有时候提交按钮点击两次才可以取消输入框软键盘,点击第一次软键盘消失,点击第二次输入框页面消失,这样用户体验不好.我的做法是用 touchstart 代替click来处理 反应快,但是有时候会出 ...

  10. Kettle学习系列之Kettle的起源

    不多说,直接上干货! Kettle起源于十年以前,本世纪初.当时啊,ETL工具千姿百态,比较流行的工具有50个左右,ETL框架数量比工具还要多些. 根据这些工具的各自起源和功能可以分为以下4种类型,如 ...