欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【重要+细节】LeetCode 149. Max Points on a Line

程序员文章站 2022-06-02 22:20:08
...

LeetCode 149. Max Points on a Line

Solution1:

参考花花酱:https://zxi.mytechroad.com/blog/geometry/leetcode-149-max-points-on-a-line/
count by slope
【重要+细节】LeetCode 149. Max Points on a Line
Time complexity:O(n2)
Space complexity:O(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 n = points.size();        
        int ans = 0;
        for (int i = 0; i < n; i++) {
            std::map<std::pair<int, int>, int> count; //map的关键字类型可以用pair!!!
            int same_points = 1;//本身的点
            int max_points = 0;
            const Point& p1 = points[i];
            for (int j = 0; j < n && j != i; ++j) {//j = i + 1始终不是很理解
                const Point& p2 = points[j];
                if (p1.x == p2.x && p1.y == p2.y)
                    ++same_points;
                else
                    max_points = max(max_points, ++count[getSlope(p1, p2)]);
            }
            ans = max(ans, same_points + max_points);             
        }
        return ans;
    }
private:
    // slope dy/dx : <dy, dx>
    std::pair<int, int> getSlope(const Point& p1, const Point& p2) {
        const int dx = p2.x - p1.x;
        const int dy = p2.y - p1.y;

        // horizontal line
        if (dy == 0) return { p1.y, 0 };
        // vertical line
        if (dx == 0) return { 0, p1.x };

        const int d = gcd(dx, dy);
        return { dy / d, dx / d };
    }

    int gcd(int m, int n) { //求最大公约数
        return n == 0 ? m : gcd(n, m % n);
    }
};

有几个需要学习的点:

1.map的关键字类型可以使std::pair类型

2.求最大公约数

辗转相除法
辗转相除法最大的用途就是用来求两个数的最大公约数。 用(a,b)来表示a和b的最大公约数。有定理: 已知a,b,c为正整数,若a除以b余c,则(a,b)=(b,c)。
一.辗转相除法
例1 。求两个正数8251和6105的最大公因数。
(分析:辗转相除→余数为零→得到结果)
解:8251=6105×1+2146
显然8251与6105的最大公因数也必是2146的因数,同样6105与2146的公因数也必是8251的因数,所以8251与6105的最大公因数也是6105与2146的最大公因数。
6105=2146×2+1813
2146=1813×1+333
1813=333×5+148
333=148×2+37
148=37×4+0
则37为8251与6105的最大公因数。
求最大公约数迭代版算法。
参考网址:https://blog.csdn.net/qq_30866297/article/details/50969950

#include <stdio.h>
int main() {
    int a, b, r;
    printf("请输入两个正整数:\n");
    scanf("%d %d", &a, &b);
    //如果a<b,交换a和b的值
    if (a < b) {// 保证a > b
        r = a;
        a = b;
        b = r;
    }
    r = b; //r初始化为较小的数
    //辗转相除法,因为r的初始值不为0,所以while语句至少会执行一次
    //直至余数为零,跳出循环
    while (r != 0) {
        r = a%b;
        a = b;
        b = r;
    }
    //输出最大公约数
    printf("最大公约数为:%d\n", a);
    return 0;
}

3.求最小公倍数

最小公倍数 = 两整数的乘积 ÷ 最大公约数