Leetcode 149. Max Points on a Line

/**
 * 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 ret = 0;
        int n = points.size();
        if (n <= 2) return n;

        unordered_map<string, int> mp;
        for (int i = 0; i != points.size(); ++i) {
            mp.clear();
            int samePoint = 0;

            // 这里是可以优化的,如果【2】【1】共线,【2】【3】共线则定有【1】【3】共线,这种情况在计算【1】的时候已经计算过了。
            for (int j = 0; j != points.size(); ++j) {

                if (i == j) continue;
                if (points[i].x == points[j].x && points[i].y == points[j].y) {
                    ++samePoint;
                    continue;
                }
                string key = get_dir(points[j].x - points[i].x, points[j].y - points[i].y);
                auto it = mp.find(key);
                if (it == mp.end()) {
                    mp[key] = 2;
                } else {
                    mp[key] += 1;
                }
            }

            ret = max (ret, samePoint + 1);   // if mp.size() == 0;
            for (auto it = mp.begin(); it != mp.end(); ++it) {
                ret = max(ret, it->second + samePoint);
            }
        }
        return ret;
    }
private:
    /*
    int gcd(int a, int b) {
        if (a < 0) a = -a;
        if (b < 0) b = -b;
        if (a < b) return gcd(b, a);
        if (b == 0) return a;
        return gcd(a - b, b);
    }
    */
    int gcd (int a, int b) {
        if (a < 0) a = -a;
        if (b < 0) b = -b;
        return b ? gcd(b, a % b) : a;
    }

    string get_dir(int x, int y) {
        int n = gcd(x, y);
        return to_string(x / n) + "," + to_string(y / n);
    }



};

参考后

/**
 * 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 ret = 0;
        int n = points.size();
        if (n <= 2) return n;

        unordered_map<string, int> mp;
        for (int i = 0; i != points.size(); ++i) {
            mp.clear();
            int samePoint = 0;

            for (int j = i + 1; j != points.size(); ++j) {

                if (points[i].x == points[j].x && points[i].y == points[j].y) {
                    ++samePoint;
                    continue;
                }
                // 这个版本得到的是和斜率差不多的意思
                // 上个版本得到的是和单位向量差不多的意思
                string key = get_dir(points[j].x - points[i].x, points[j].y - points[i].y);
                auto it = mp.find(key);
                if (it == mp.end()) {
                    mp[key] = 2;
                } else {
                    mp[key] += 1;
                }
            }

            // 有 n 个相同的点 mp.size() == 0; 
            ret = max (ret, samePoint + 1); 
            for (auto it = mp.begin(); it != mp.end(); ++it) {
                ret = max(ret, it->second + samePoint);
            }
        }
        return ret;
    }
private:
    /*
    int gcd(int a, int b) {
        if (a < 0) a = -a;
        if (b < 0) b = -b;
        if (a < b) return gcd(b, a);
        if (b == 0) return a;
        return gcd(a - b, b);
    }
    */
    // a, b 可正可负 例如 -8 与 -4 得 -4,虽然不是最大公约数但正是我们想要的
    int gcd (int a, int b) {
        // if (a < 0) a = -a;
        // if (b < 0) b = -b;
        return b ? gcd(b, a % b) : a;
    }

    string get_dir(int x, int y) {
        int n = gcd(x, y);
        return to_string(x / n) + "," + to_string(y / n);
    }



};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值