LeetCode Max Points on a Line
2015-05-16 10:16
316 查看
平面上的点,求共线的最大点数。
Naive解法,对每两个点确定的直线,计算与这条直线共线的点数。未做优化,147ms。
可以用hash对其进行优化(4ms过)。思想是,对每一个点,计算其它节点与他的斜率,放入一个hashtable并计数,最终取hashtalbe中累计最多的一个。
注意计算斜率的宏Slope,当两点斜率为无穷大时,我们设斜率为float的最大值,保证了逻辑上的Inf != any other && Inf == Inf,注意这里的等号和不等号是针对与二进制的物理表示的,因为我们在hashtable中,key的相等是依据直接比较二进制物理表示。
当两点斜率是0时,我们手动赋值0.0,否则可能出现-0.0物理内存不等于0.0的情况,从而在hashtable中认为是不同的key。
也就是说,naive中key的比较用的是C语言中的==和!=,所以不用关心物理表示;但在我们写的hashtable中,key的相同依据物理内存,因此需要我们对Slope做额外的确保。
Naive解法,对每两个点确定的直线,计算与这条直线共线的点数。未做优化,147ms。
/** * Definition for a point. * struct Point { * int x; * int y; * } */ // (在float的==比较中,隐含Nan != any not Nan,0.0 == -0.0,尤其注意!!) #define Slope(i, j) (((double)(j.y) - i.y) / (j.x - i.x)) int maxPoints(struct Point* points, int pointsSize) { int i, j, k, res = 2; if (pointsSize <= 2) // 少于3个点,返回点数。 return pointsSize; for (i = 0 ; i < pointsSize ; i++) for (j = 0 ; j < pointsSize ; j++) { if (i == j) continue; int p = 2; // 至少有两个点共线了 for (k = 0 ; k < pointsSize ; k++) { if (k == i || k == j) continue; // 三点不同 if (points[i].x == points[k].x && points[i].y == points[k].y) p++; // 重合点 else if (points[j].x == points[k].x && points[j].y == points[k].y) p++; // 重合点 else if (points[i].x == points[j].x && points[j].x == points[k].x) p++; // 斜率均不存在时 else if (Slope(points[i], points[j]) == Slope(points[j], points[k])) p++; // 否则,其中斜率之一存在,判断斜率是否相等。(在float的==比较中,隐含Nan != any not Nan,0.0 == -0.0,尤其注意!!) } if (p > res) res = p; } return res; }
可以用hash对其进行优化(4ms过)。思想是,对每一个点,计算其它节点与他的斜率,放入一个hashtable并计数,最终取hashtalbe中累计最多的一个。
注意计算斜率的宏Slope,当两点斜率为无穷大时,我们设斜率为float的最大值,保证了逻辑上的Inf != any other && Inf == Inf,注意这里的等号和不等号是针对与二进制的物理表示的,因为我们在hashtable中,key的相等是依据直接比较二进制物理表示。
当两点斜率是0时,我们手动赋值0.0,否则可能出现-0.0物理内存不等于0.0的情况,从而在hashtable中认为是不同的key。
也就是说,naive中key的比较用的是C语言中的==和!=,所以不用关心物理表示;但在我们写的hashtable中,key的相同依据物理内存,因此需要我们对Slope做额外的确保。
#define Slope(i, j) (j.x == i.x ? 4294967295.0f : \ j.y == i.y ? 0.0f : ((float)(j.y-i.y)) / (j.x-i.x)) struct Mystruct { float slope; int num; struct B_HashHandle hh; }; int maxPoints(struct Point* points, int pointsSize) { int i, j, k, res = 0; if (pointsSize <= 2) // 少于3个节点返回点数 return pointsSize; struct Mystruct* mystruct = malloc(sizeof(struct Mystruct) * pointsSize); // 最多hashtable中可能插入点数相同个元素 struct B_HashTable* ht = hashInit(struct Mystruct); for (i = 0 ; i < pointsSize ; i++) { hashClear(ht); int t = 0, cnt = 0; // cnt累计了重合点个数 for (j = i+1 ; j < pointsSize ; j++) { // j从i+1开始,必须保证0.0 == -0.0的判断(在这里WA了,用GDB调了半天) if (points[i].x == points[j].x && points[i].y == points[j].y) cnt++; else { mystruct[t].slope = Slope(points[i], points[j]); struct Mystruct* ret = hashSafeInsertField(ht, mystruct[t], slope); if (ret) ret->num++; else { mystruct[t].num = 1; t++; } } } if (cnt > res) // 若没有此举,考虑这样的例子:三点重合,则以下循环不会发生,res不会更新为cnt res = cnt; struct Mystruct* iter = hashIter(ht); for ( ; iter ; iter = hashIterNext(ht, iter)) if (cnt + iter->num > res) res = cnt + iter->num; } hashDestroy(ht); free(mystruct); return res + 1; // 最后要算上自己(我们的工作是,对每一个点,计算其它节点与他的斜率,放入一个hashtable并计数,最终还需累计他自己共线) }
相关文章推荐
- 【leetcode刷题笔记】Max Points on a Line
- [Leetcode][python]Max Points on a Line
- LeetCode刷题笔记(穷举):max-points-on-a-line
- [leetcode] 149. Max Points on a Line
- LeetCode 149. Max Points on a Line
- Leetcode: Max Points on a Line
- LeetCode--max-points-on-a-line
- LeetCode-Max Points on a Line
- **Leetcode 149. Max Points on a Line
- Leetcode Max Points on a Line
- LEETCODE: Max Points on a Line
- 【LeetCode】Max Points on a Line
- LeetCode: Max Points on a Line 解题报告
- Leetcode: Max Points on a Line
- Leetcode Max Points on a Line 解题报告
- LeetCode | Max Points on a Line
- leetcode: Max Points on a Line
- leetcode 149. Max Points on a Line 计算斜率的问题 + 直接暴力求解即可
- [LeetCode]149. Max Points on a Line
- leetcode Max Points on a Line