Leetcode - Max Points on a Line

12 篇文章 0 订阅
[分析]
两条直线若包含一个公共点且斜率相同,则为同一条直线。因此依次将数组中各点设为公共点,并计算所有未当过公共点的其他点同当当前公共点形成直线的斜率,使用哈希表保存各斜率直线上的点数,遍历过程中同时更新维护一条直线上包含的最多点数。
实现1中key直接就是double类型的斜率,实现时有几个注意点:
1)斜率为0时要单独判断并显式赋值为0,double类型0 和 -0是不等的
2)需要考虑输入中可能存在重复点
3)map,same, max为什么要放在循环里头定义?为什么需要max 和ret两个变量?因为它们统计的是以points[i]为公共点时数据,max可以看做时局部最大值,ret是全局最大值,不可混淆
实现2中key是斜率计算分式化简后的结果,避免使用double实际计算出斜率,参考
[url]https://leetcode.com/discuss/9011/c-o-n-2-solution-for-your-reference[/url]

PS: leetcode 允许加打印语句进行调试啦~

/**
* Definition for a point.
* class Point {
* int x;
* int y;
* Point() { x = 0; y = 0; }
* Point(int a, int b) { x = a; y = b; }
* }
*/
public class Solution {
// Method 2
public int maxPoints(Point[] points) {
if (points == null) return 0;
if (points.length < 3) return points.length;
int globalMax = 2;
int N = points.length;
for (int i = 0; i < N - 2; i++) {
HashMap<String, Integer> map = new HashMap<String, Integer>();
int same = 0;
int localMax = 1; //attention, not init to 0
int x1 = points[i].x, y1 = points[i].y;
for (int j = i + 1; j < N; j++) {
int x2 = points[j].x, y2 = points[j].y;
int deltaX = x2 - x1;
int deltaY = y2 - y1;
int gcd = gcd(deltaX, deltaY);
if (gcd == 0) {
same++;
continue;
}
deltaX /= gcd;
deltaY /= gcd;
String slope = deltaY + "/" + deltaX;
if (map.containsKey(slope))
map.put(slope, map.get(slope) + 1);
else
map.put(slope, 2);
localMax = Math.max(localMax, map.get(slope));
}
globalMax = Math.max(globalMax, localMax + same);
}
return globalMax;
}
public int gcd(int a, int b) {
return b != 0 ? gcd(b, a % b) : a;
}
// Method 1
public int maxPoints1(Point[] points) {
if (points == null) return 0;
if (points.length < 3) return points.length;
int ret = 0;
int N = points.length;
for (int i = 0; i < N; i++) {
HashMap<Double, Integer> map = new HashMap<Double, Integer>();
long x1 = points[i].x, y1 = points[i].y;
int same = 0;
int max = 1;
for (int j = i + 1; j < N; j++) {
long x2 = points[j].x, y2 = points[j].y;
if (x1 == x2 && y1 == y2) {// specail attention
same++;
} else if (x1 == x2) {
if (map.containsKey(Double.MAX_VALUE))
map.put(Double.MAX_VALUE, map.get(Double.MAX_VALUE) + 1);
else
map.put(Double.MAX_VALUE, 2);
max = Math.max(max, map.get(Double.MAX_VALUE));
} else {
double slope = 0;
if (y1 == y2)
slope = 0; // special attention, consider case[2, 3], [3, 3], [-5, 3]
else
slope = 1.0 * (y2 - y1) / (x2 - x1);;
if (map.containsKey(slope))
map.put(slope, map.get(slope) + 1);
else
map.put(slope, 2);
max = Math.max(max, map.get(slope));
}
}
// System.out.println(max + " " + same);
ret = Math.max(ret, max + same);
}
return ret;
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值