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;
}






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章