973. 最接近原点的 K 个点-k数组维护+二分查找

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;
}

这个运行情况要多好了:
在这里插入图片描述

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值