面试:数组:Topk _1
2016-05-14 23:50
471 查看
题目
求一维数组中最小的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; } }
相关文章推荐
- 程序员必须知道的10大基础实用算法及其讲解
- 微软面试100题-70
- 微软面试100题-69
- Java程序员的日常 —— static的用法讲解实践
- 剑指offer 面试题29:数组中出现次数超过一半的数字及其变形(腾讯2015秋招 编程题4)
- 机器学习常见面试题
- 软件众包 业余主义的复兴
- iOS面试题 汇总
- 软件众包 业余主义的复兴
- Java多线程和并发基础面试问答
- Android 面试题
- Java 常用排序算法/程序员必须掌握的 8大排序算法
- 65 个职场很有技巧的回答
- Java多线程和并发基础面试问答
- web前端面试题集锦
- java面试
- 阿里巴巴前端岗位面试题
- 【36】按层打印二叉树
- iOS_面试题
- 程序员常用网站