参考花花酱:https://zxi.mytechroad.com/blog/geometry/leetcode-149-max-points-on-a-line/
count by slope
Time complexity: O(n2) O ( n 2 )
Space complexity: O(n) 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 & 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 :
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);
}
};
有几个需要学习的点:
辗转相除法
辗转相除法最大的用途就是用来求两个数的最大公约数。 用(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
int main() {
int a, b, r;
printf("请输入两个正整数:\n");
scanf("%d %d", &a, &b);
//如果a
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;
}
最小公倍数 = 两整数的乘积 ÷ 最大公约数