面试:数组:Topk _1

来源:互联网 发布:labview数组最大值 编辑:程序博客网 时间:2024/05/16 05:31

题目

求一维数组中最小的k个数字


快排算法

复杂度:O(klgn)

import java.util.*;class Solution{     //选择一个数,将数组分为大小两个部分    public int partition(int data[],int start,int end){        int pivotvalue=data[start];        while(start<end){            while(start<end && data[end]>=pivotvalue)                --end;            // 将比pviot小的元素移动到低端,此时right空,等待低位比pviotvalue大的数补上            data[start]=data[end];            while(start<end && data[start]<=pivotvalue)                ++start;            //此时比pviot大的元素移动到了高端,此时left位相当于空,等待高位比pivotalue小的数补上            data[start]=data[end];        }        //当start=end,完成一次快速排序,此时left相当于空,等待pivotvalue补上        data[start] = pivotvalue;        return start;    }    // 若返回的小标是k-1,则结束;否则,调用partition到下标为k-1    public void getTopk(int[] data,int k){        int start = 0,end = data.length-1;        int index=partition(data,start,end);        while(index!=k-1){            if(index>k-1){                // 从index前面重新查找                 end = index-1;                 index = partition(data,start,end);            }else{                start=end-1;                index=partition(data,start,end);            }        }        for(int i=0;i<k;i++)            System.out.println(data[i]+"\t");    }}

堆排序算法

复杂度:O (nlgK)

算法;
1. 创建小根堆,初始化大小为k,堆顶为堆得最大元素
2. 扫描数组,往最小堆插入数据,如果堆得元素个数达到k,那么新元素需要和堆顶元素比较,如果小于堆顶,插入新元素。
3. 最终得到k个最小元素。


import java.util.*;class MinHeap{    // 堆存储数组    private int[] data;    // 构建小根堆    public  MinHeap(int[] data){        this.data=data;        bulidHeap();    }    // 数组转换为小根堆    private void bulidHeap(){        for(int i=(data.length)/2-1;i>=0;i--)            heapify(i); // 对孩子节点调用heapify    }     //简化写法    private void heapify(int k){        int N=data.length;        while(2*k<=N){            int j=2*k;            if(j<N && less(j,j+1))                j++;            if(!less(k,j))                break;            exch(k,j);            k=j;        }    }    /*    // 好理解的写法    private void heapify(int k){        // 获取左右节点的数组的下标        int l=left(i);        int r =right(i);        // 临时变量         int smallest=i;         //若存在左节点,且左节点的值下于根节点          if(l<data.length && data[l]<data[i])             smalleat=l;         if(r<data.length && data[r]<data[smalleat])            smalleat=r;          // 左右节点都大于根节点直接return           if(i==smallest)             return;          //交换节点           swap(i,smalleat);           // 交替后左右子树有影响,对收影响的子树再次heapify            heapify(smalleat);    }    */    private boolean less(int i,int j)    {        if(data[i]<data[j])            return true;        else            return false;    }    private void exch(int i, int j)    {        int key=data[i];        data[i]=data[j];        data[j]=key;    }    public int getRoot(){        return data[0];    }    // 替换根节点,并重新heapify    public void setRoot(int root)    {        data[0]=root;        heapify(0);    }}public class Solution{    public static void main(String[] args){        // 元数据        int[] data={56,275,12,6,45,478,41,1236,456,12,546,45};        //top5         int[] top5=topk(data,5);         for(int i=0;i<5;i++)             System.out.println(top5[i]);    }     private static int[] topk(int[] data,int k){        //取得k个元素放入一个数组topk中        int[] topk=new int [k];        for(int i=0;i<k;i++)            topk[i]=data[i];        // 转换为小根堆        MinHeap heap =new MinHeap(topk);        for(int i=k;i<data.length;i++){            int root = heap.getRoot();            //根据大于堆中最小的数 ,替换堆中的根节点,再转换为堆            if(data[i]>root)                heap.setRoot(data[i]);        }        return topk;        }    }
0 0
原创粉丝点击