面试题 16.14. 最佳直线-数学暴力解法
给定一个二维平面及平面上的 N 个点列表Points,其中第i个点的坐标为Points[i]=[Xi,Yi]。请找出一条直线,其通过的点的数目最多。
设穿过最多点的直线所穿过的全部点编号从小到大排序的列表为S,你仅需返回[S[0],S[1]]作为答案,若有多条直线穿过了相同数量的点,则选择S[0]值较小的直线返回,S[0]相同则选择S[1]值较小的直线返回。
示例:
输入: [[0,0],[1,1],[1,0],[2,0]]
输出: [0,2]
解释: 所求直线穿过的3个点的编号为[0,2,3]
对于这个题目,其实,一个很好的方法是实用并查集,以前我做过,但是其实都差不多,这题比较优化的解法也不会比暴力解法好太多,因为这个题目问题的性质决定了,其时间复杂度不会太好,解题代码如下:
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* bestLine(int** points, int pointsSize, int* pointsColSize, int* returnSize){
int *re=(int*)malloc(sizeof(int)*2);
*returnSize=2;
int r[pointsSize];
int max=0;
for(int i=0;i<pointsSize;i++){
for(int k=i+1;k<pointsSize;k++){
r[k]=1;
}
for(int j=i+1;j<pointsSize;j++){
if(r[j]==1){
int size=0;
r[j]=0;
long long x1=points[j][0]-points[i][0];
long long y1=points[j][1]-points[i][1];
// printf("%ld %ld ",k1,k2);
for(int k=j+1;k<pointsSize;k++){
long long x2=points[k][0]-points[i][0];
long long y2=points[k][1]-points[i][1];
if(x1*y2==y1*x2){
printf("||");
r[k]=0;
size++;
}
}
if(size>max){
max=size;
re[0]=i;
re[1]=j;
}
}
else{
continue;
}
}
}
if(max==0){
re[0]=0;
re[1]=1;
}
return re;
}