973. 最接近原点的 K 个点-k数组维护+二分查找
给定一个数组 points ,其中 points[i] = [xi, yi] 表示 X-Y 平面上的一个点,并且是一个整数 k ,返回离原点 (0,0) 最近的 k 个点。
这里,平面上两点之间的距离是 欧几里德距离( √(x1 - x2)2 + (y1 - y2)2 )。
你可以按 任何顺序 返回答案。除了点坐标的顺序之外,答案 确保 是 唯一 的。
示例 1:
输入:points = [[1,3],[-2,2]], k = 1
输出:[[-2,2]]
解释:
(1, 3) 和原点之间的距离为 sqrt(10),
(-2, 2) 和原点之间的距离为 sqrt(8),
由于 sqrt(8) < sqrt(10),(-2, 2) 离原点更近。
我们只需要距离原点最近的 K = 1 个点,所以答案就是 [[-2,2]]。
示例 2:
输入:points = [[3,3],[5,-1],[-2,4]], k = 2
输出:[[3,3],[-2,4]]
(答案 [[-2,4],[3,3]] 也会被接受。)
对于这题我们维护了一个数组长度为K得数组
/*** Return an array of arrays of size *returnSize.* The sizes of the arrays are returned as *returnColumnSizes array.* Note: Both indexned array and *columnSizes array must be malloced, assume caller calls free().*/int find_index(int *a,int size,int v){int high=size-1;int low=0;if(a[size-1]<=v){return -1;}else{while(low<=high){int mid=(high+low)/2;if(a[mid]>v){high=mid-1;}else{low=mid+1;}}return low;}}
int** kClosest(int** points, int pointsSize, int* pointsColSize, int k, int* returnSize, int** returnColumnSizes) {int **a=(int **)malloc(sizeof(int*)*k);int min_index[k];int index_record[k];*returnColumnSizes = malloc(sizeof(int) * k);for(int i=0;i<k;i++){a[i]=(int *)malloc(sizeof(int)*2);}for(int i=0;i<k;i++){(*returnColumnSizes)[i] = 2;}for(int i=0;i<k;i++){int z=points[i][0]*points[i][0]+points[i][1]*points[i][1];min_index[i]=points[i][0]*points[i][0]+points[i][1]*points[i][1];// printf("z %d ",z);index_record[i]=i;if(i==0){continue;}else{int j=i-1;for(;j>=0;j--){if(min_index[j]>z){min_index[j+1]=min_index[j];index_record[j+1]=index_record[j];}else{break;}}// printf("-- %d ",j);if(j!=0){min_index[j+1]=z;index_record[j+1]=i;}if(j==0){if(min_index[j]>z){min_index[0]=z;index_record[0]=i;}else{min_index[j+1]=z;index_record[j+1]=i;}}// printf("j %d",j);}// for(int iz=0;iz<i;iz++){// printf("*%d ",min_index[iz]);// }// printf("\n");}for(int i=k;i<pointsSize;i++){int v=points[i][0]*points[i][0]+points[i][1]*points[i][1];int find_index_min=find_index(min_index,k,v);// printf(" find_index_min %d ",find_index_min);if(find_index_min==-1){continue;}else{for(int j=k-1;j>find_index_min;j--){min_index[j]=min_index[j-1];index_record[j]=index_record[j-1];}min_index[find_index_min]=points[i][0]*points[i][0]+points[i][1]*points[i][1];index_record[find_index_min]=i;}}for(int i=0;i<k;i++){a[i][0]=points[index_record[i]][0];a[i][1]=points[index_record[i]][1];}*returnSize=k;return a;
}
其运行情况如下:
当然上面这个方法是很粗糙的,而且有多余的内存消耗,博主发现,内存还可以优化,下面是优化后的代码:
/*** Return an array of arrays of size *returnSize.* The sizes of the arrays are returned as *returnColumnSizes array.* Note: Both indexned array and *columnSizes array must be malloced, assume caller calls free().*/int find_index(int *a,int size,int v){int high=size-1;int low=0;if(a[size-1]<=v){return -1;}else{while(low<=high){int mid=(high+low)/2;if(a[mid]>v){high=mid-1;}else{low=mid+1;}}return low;}}
int** kClosest(int** points, int pointsSize, int* pointsColSize, int k, int* returnSize, int** returnColumnSizes) {int min_index[k];*returnColumnSizes = malloc(sizeof(int) * k);for(int i=0;i<k;i++){(*returnColumnSizes)[i] = 2;}for(int i=0;i<k;i++){int z=points[i][0]*points[i][0]+points[i][1]*points[i][1];min_index[i]=points[i][0]*points[i][0]+points[i][1]*points[i][1];// printf("z %d ",z);int x=points[i][0];int y=points[i][1];if(i==0){continue;}else{int j=i-1;for(;j>=0;j--){if(min_index[j]>z){min_index[j+1]=min_index[j];points[j+1][0]=points[j][0];points[j+1][1]=points[j][1];}else{break;}}// printf("-- %d ",j);if(j!=0){points[j+1][0]=x;points[j+1][1]=y;min_index[j+1]=z;}if(j==0){if(min_index[j]>z){min_index[0]=z;points[0][0]=x;points[0][1]=y;}else{min_index[j+1]=z;points[j+1][0]=x;points[j+1][1]=y;}}// printf("j %d",j);}// for(int iz=0;iz<i;iz++){// printf("*%d ",min_index[iz]);// }// printf("\n");}for(int i=k;i<pointsSize;i++){int v=points[i][0]*points[i][0]+points[i][1]*points[i][1];int find_index_min=find_index(min_index,k,v);// printf(" find_index_min %d ",find_index_min);if(find_index_min==-1){continue;}else{for(int j=k-1;j>find_index_min;j--){min_index[j]=min_index[j-1];points[j][0]=points[j-1][0];points[j][1]=points[j-1][1];}min_index[find_index_min]=points[i][0]*points[i][0]+points[i][1]*points[i][1];points[find_index_min][0]=points[i][0];points[find_index_min][1]=points[i][1];}}*returnSize=k;return points;
}
这个运行情况要多好了: