面试题四十:数组中最小的k个数

 

方法一:先排序后寻找前k个数;
方法二:受面试题三十九,寻找超过一半的数的启发,只把里面的middle改成k-1就行;

void HalfNum( int [ ] Array ,int k){

             int start=0;
             int end=Array.length-1;
             int index=Patition(Array ,start ,end);
             //不求排序,只求不断向中间靠近
             while(index!=k){
                      if(index>k){
                              end=index-1;
                      }
                      else 
                          start=index+1;
                   index=Patition(Array ,start ,end)
             }    
             for(int i=0;i<k;i++) {
                      System.out.print(Array[i]+" ");
                  }
                  System.out.println();
      }


    int Patition( int [] a,int be,int end){
                 int inter=a[be];//把起始位置作为主元
                 int L=be+1;
                 int R=end;
                 int b;
                 while(L<=R)///数组都遍历完了即R与L交错时停止循环 
                   {
                       while(L<=R&&inter>=a[L]) L++;
                       while(L<=R&&inter<a[R]) R--;
                        if(L<R)
                         {b=a[L]; a[L]=a[R]; a[R]=b;}
                         ///交换位置,把比主元大的放后面 ,比主元小的放前面
                          }
                   a[be]=a[R];a[R]=inter;///交换位置把主元放进去作为间隔 
                  return R;
          }

方法三:适合处理**海量的数据**,创建一个大小为k的容器,首先填满,再寻找最大值,比较替换;

 void  MinK(int[] Array,int k) {
         int[] A_k = new int[k]; //K堆的大小开辟空间
         int i=0;
         //填满K堆
         while(i<k){
              A_k[i] = Array[i];
              i++;
         }
         BuildHeap(A_k);//建堆      
         while(i<Array.length) {
              if(Array[i]<A_k[0]) {
                  A_k[0]=Array[i];
                  Heapify(0, A_k);/// 调堆
              }
              i++;
         }
          for(int j=0;j<k;j++) {
                      System.out.print(A_k[j]+" ");
                  }
                  System.out.println();
     }

     // 建堆,二叉树用数组表示:根节点下标为n=0;左子树为2n+1,右子树为2n+2;求父节点则为(n-1)/2
     public static void BuildHeap(int[] Array) {
         //找到最后一个非叶子节点开始,自底向上调整
         for(int i=Array.length/2-1;i>=0;i--) 
              Heapify(i, Array);
         
     }  

     // 调堆,就是把最大值最为根节点i
    //以i为根节点建立大顶堆 
     public static void Heapify(int i,int[] Array){
         int left = i*2+1;//左孩子
         int right = i*2+2;//右孩子 
         //寻找最大值下标
         int biggest = i;
         if(left < Array.length && Array[left]>Array[i]
              biggest = left;
         if(right<Array.length && Array[biggest]<Array[right])
              biggest = right;

         //如果根节点就是最大,那么下面的子树就不用管
         if(i == biggest)    return;

         //否则两个值交换后,调整下面交换后的堆
         int temp = Array[i];
         Array[i] = Array[biggest]
         Array[biggest] = temp;     
         Heapify(biggest, Array);

     }

 

posted @ 2020-03-29 16:25  浪波激泥  阅读(233)  评论(0编辑  收藏  举报