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.

分析

1、首先的想法是根据两点确定一条直线,之后判断第三点是否在直线上,为三层迭代(循环)。时间复杂度O(n^3)。

2、处理重复的点:先把点映射到map中,保存点出现的次数。之后,创建点和次数的结构体,保存到vector中,使用1求得max。

3、使用map的问题,题目已经定义了struct,并且没有对运算符<进行重载,因此必须额外定义比较规则。方法见:它

复杂度


注意

1、集合中没有元素,即没有点。
2、集合中重复的点,比如(0,0)出现了两次,那么这样算两个点。
3、map若使用结构体作为key,必须对运算符<进行重载,因为map需要比较规则,构建树。
4、直线分两种,一种是x轴的垂线,另外一种是有斜率的直线。

5、点的统计规则:curnum += points[k].value;

输入

1、空
2、一个点
3、两个重复的点
4、多加几个点测试

CODE

Code1: 结构体内重载<

#include <iostream>
#include <vector>
#include <string>
#include <stack>
#include <map>
#include <stdexcept>

using namespace std;



struct Point {
    int x;
    int y;
    Point() : x(0), y(0) {}
    Point(int a, int b) : x(a), y(b) {}
    bool operator < (const Point& pointB) const
    {
        if (x != pointB.x) {
            return x < pointB.x;
        } else {
            return y < pointB.y;
        }
    }
};

struct PointValue {
    Point point;
    int value;
    PointValue() : value(0) {}
};


/**
 * Definition for a point.
 * struct Point {
 *     int x;
 *     int y;
 *     Point() : x(0), y(0) {}
 *     Point(int a, int b) : x(a), y(b) {}
 * };
 */
class Solution {
public:
    int maxPoints(vector<Point> &points) {
        int maxnum = 0;
        map<Point, int> imap;
        insertToMap(points, imap);
        vector<PointValue> newPoints;
        clearPoints(newPoints, imap);
        maxnum = scanVector(newPoints);
        return maxnum;
    }

    void insertToMap(vector<Point> &points, map<Point, int> &imap) {

        for (auto itVar = points.begin(); itVar != points.end(); ++itVar) {
            Point pVar = *itVar;
            auto it = imap.find(pVar);
            if (it != imap.end()) {
                // already exist
//                int t = it->second;
//                it->second = t + 1;
                ++(it->second);
            } else {
                // insert to imap
                imap.insert( make_pair(pVar, 1) );
            }
        }
    }

    void clearPoints(vector<PointValue> &points, map<Point, int> &mymap) {
        for (auto it = mymap.begin(); it != mymap.end(); ++it) {
            PointValue pv;
            pv.point = it->first;
            pv.value = it->second;
            points.push_back(pv);
        }
    }

    int scanVector(vector<PointValue> &points) {
        int maxnum = 0;
        if (points.size() == 0) {
            return 0;
        } else if(points.size() == 1) {
            return points[0].value;
        } else {
            // number of points more than two
            int vecSize = points.size();
            for (int i = 0; i != vecSize; ++i) {
                for(int j = i + 1; j != vecSize; ++j) {
                    // form a line
                    int curnum = points[i].value + points[j].value;
                    if (points[i].point.x == points[j].point.x) {
                        // vertical
                        for(int k = j + 1; j != vecSize; ++k) {
                            if (points[i].point.x == points[k].point.x) {
                                curnum += points[k].value;
                                // ++curnum;
                            }
                        }
                    } else {
                        // a line with slope
                        double slpoe = (static_cast<double>(points[i].point.y - points[j].point.y)) / (points[i].point.x - points[j].point.x);
                        for(int k = j + 1; k != vecSize; ++k) {
                            double slope1 = (static_cast<double>(points[i].point.y - points[k].point.y)) / (points[i].point.x - points[k].point.x);
                            if (slpoe == slope1) {
                                curnum += points[k].value;
                                // ++curnum; //it is not right!!!
                            }
                        }
                    }
                    if (curnum > maxnum) {
                        maxnum = curnum;
                    }
                }
            }
        }
        return maxnum;
    }

    // all kinds of lines
};


int main()
{
    vector<Point> t1;
    vector<Point> t2(1);
    vector<Point> t3(2);
    vector<Point> t4(2);
    Point t;
    t.x = 2; t.y = 1;
    t4.push_back(t);
    t.x = 4; t.y = 2;
    t4.push_back(t);
    t.x = 1; t.y = 2;
    t4.push_back(t);


    Solution so;
    cout << so.maxPoints(t1) << endl;
    cout << so.maxPoints(t2) << endl;
    cout << so.maxPoints(t3) << endl;
    cout << so.maxPoints(t4) << endl;
    return 0;
}


Code2: 外部定义规则

#include <iostream>
#include <vector>
#include <string>
#include <stack>
#include <map>
#include <stdexcept>

using namespace std;



struct Point {
    int x;
    int y;
    Point() : x(0), y(0) {}
    Point(int a, int b) : x(a), y(b) {}
};

struct PointValue {
    Point point;
    int value;
    PointValue() : value(0) {}
};

bool my_cmp(const Point &a, const Point b) {
    if (a.x != b.x) {
        return a.x < b.x;
    } else {
        return a.y < b.y;
    }
}
typedef bool (*comp)(const Point &a, const Point b);



/**
 * Definition for a point.
 * struct Point {
 *     int x;
 *     int y;
 *     Point() : x(0), y(0) {}
 *     Point(int a, int b) : x(a), y(b) {}
 * };
 */
class Solution {
public:
    int maxPoints(vector<Point> &points) {
        int maxnum = 0;
        map<Point, int, comp> imap(my_cmp);
        insertToMap(points, imap);
        vector<PointValue> newPoints;
        clearPoints(newPoints, imap);
        maxnum = scanVector(newPoints);
        return maxnum;
    }

    void insertToMap(vector<Point> &points, map<Point, int, comp> &imap) {
        for (auto itVar = points.begin(); itVar != points.end(); ++itVar) {
            Point pVar = *itVar;
            auto it = imap.find(pVar);
            if (it != imap.end()) {
                // already exist
//                int t = it->second;
//                it->second = t + 1;
                ++(it->second);
            } else {
                // insert to imap
                imap.insert( make_pair(pVar, 1) );
            }
        }
    }

    void clearPoints(vector<PointValue> &points, map<Point, int, comp> &imap) {
        for (auto it = imap.begin(); it != imap.end(); ++it) {
            PointValue pv;
            pv.point = it->first;
            pv.value = it->second;
            points.push_back(pv);
        }
    }

    int scanVector(vector<PointValue> &points) {
        int maxnum = 0;
        if (points.size() == 0) {
            return 0;
        } else if(points.size() == 1) {
            return points[0].value;
        } else {
            // number of points more than two
            int vecSize = points.size();
            for (int i = 0; i != vecSize; ++i) {
                for(int j = i + 1; j != vecSize; ++j) {
                    // form a line
                    int curnum = points[i].value + points[j].value;
                    if (points[i].point.x == points[j].point.x) {
                        // vertical
                        for(int k = j + 1; k != vecSize; ++k) {
                            if (points[i].point.x == points[k].point.x) {
                                curnum += points[k].value;
                            }
                        }
                    } else {
                        // a line with slope
                        double slpoe = (static_cast<double>(points[i].point.y - points[j].point.y)) / (points[i].point.x - points[j].point.x);
                        for(int k = j + 1; k != vecSize; ++k) {
                            double slope1 = (static_cast<double>(points[i].point.y - points[k].point.y)) / (points[i].point.x - points[k].point.x);
                            if (slpoe == slope1) {
                                curnum += points[k].value;
//                                ++curnum; //it is wrong.
                            }
                        }
                    }
                    if (curnum > maxnum) {
                        maxnum = curnum;
                    }
                }
            }
        }
        return maxnum;
    }
};


int main()
{
    vector<Point> t1;
    vector<Point> t2(1);
    vector<Point> t3(2);
    vector<Point> t4(2);
    Point t;
    t.x = 2; t.y = 1;
    t4.push_back(t);
    t.x = 4; t.y = 2;
    t4.push_back(t);
    t.x = 1; t.y = 2;
    t4.push_back(t);


    Solution so;
    cout << so.maxPoints(t1) << endl;
    cout << so.maxPoints(t2) << endl;
    cout << so.maxPoints(t3) << endl;
    cout << so.maxPoints(t4) << endl;
    return 0;
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值