您的位置:首页 > 职场人生

面试:数组: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;

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: