找出无序数组中最小的前k个数

基本思想:在快速排序的基础上进行改进。

时间复杂度:O(nlogn)。

具体代码如下:

package test;

public class Test {
	
	public static int N = 4; //找出最小的4个数
	public static void QuickSort(int a[],int left,int right){
		int i=left;
		int j=right;
		int temp = a[i];
		if(left>=right)
			return ;
		while(i<j){
			while(i<j&&a[j]>temp)
				j--;
			if(i<j){
				a[i++]=a[j];
			}
			while(i<j&&a[i]<temp){
				i++;
			}
			if(i<j){
				a[j--]=a[i];
			}
		}
		a[j]=temp;
		
		if(i>N && left<N)  //在中轴数左边继续寻找
			QuickSort(a,left,i-1);
		
		if(i<=N && right>=N)  //在中轴数右边继续寻找
		    QuickSort(a,i+1,right);
		
	}
	

	public static void main(String[] args) {
		
		int array[] = { 1, 5, 2, 9, 4, 3, 7, 8, 6, 10 };
		
		QuickSort(array,0,N);
		
		for(int i=0;i<N;i++)
			System.out.print(array[i]+" ");
		//System.out.print(Arrays.toString(array));
	}

}

寻找无序数组中的第K大数和前K大数,两个问题互相可以转化。如果可以找到第K大数,那么只再需要O(N)就可以找齐剩余的前K大数。如果可以找到前K大数,那么只再需要O(K)就可以找到第K大数。

先排序,在找第K个。O(NlgN)
快速排序的思想,可以做到平均效率O(N)
随机选一个元素,把所有小于等于这个元素的数移到左边,所有大于这个元素的数移动到右边。如果这个元素成了第K个数,直接返回这个数。
如果左边的个数大于K,不管右边的数了,在左边重复上面的过程。
如果左边的个数等于T<K,不管左边的数了,重复上面的过程,只是K=K-T-1。
平均情况下,第一次划分的时间复杂度是O(N),第二次是O(N/2),总共是O(N+N/2+N/4+...)=O(N)
package test;

public class Test {
	
	public static int QuickSort(int a[],int left,int right,int K){
		int i=left;
		int j=right;
		if(K>right-left+1) 
			return -1;
		if(left>right)
			return -1;
		
		int temp = a[i];
		while(i<j){
			while(i<j&&a[j]>temp)
				j--;
			if(i<j){
				a[i++]=a[j];
			}
			while(i<j&&a[i]<temp){
				i++;
			}
			if(i<j){
				a[j--]=a[i];
			}
		}
		a[i]=temp;
		
		int move = i-left+1;  //已经移动的步数,关键!
		
		if(move==K){
			return a[i];
		}
		else if(move>K){
			return QuickSort(a,left,i-1,K);
		}
		else{
			return QuickSort(a,i+1,right,K-move);
		}
		
	}
	

	public static void main(String[] args) {
		
		int array[] = { 1, 5, 2, 9, 4, 3, 7, 8, 6, 10 };
		
		int k = 5;
		System.out.println(QuickSort(array,0,9,k));
		
	}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值