找出数组中最小的k个元素

题目:输入n个整数,输出整数中最小的k个元素。


思路:

1.朴素算法,利用random快排,在nlgn时间内得到排序好的数组,然后输出前k个。时间复杂度有点高啊~

2.对想法1进行优化,是否可以先对k个数进行排序,时间复杂度klgk,然后对一个排好序的数组进行二分插入需要lgk的时间,做n-k次,则可以完成,时间复杂度为nlgk


代码如下:


	int piviotion(int*a,int p,int q){
		int pivot = a[q];
		int i=p;
		int j=p;
		for (;j<q;j++)
		{
			if (a[j]<pivot)
			{
				int temp = a[j];
				
				a[j] = a[i];
				a[i] = temp;
				i++;
			}
		}

		a[q] = a[i];
		a[i] = pivot;

		return i;
	}
	void randomQuickSort(int*a,int p,int q){
		//randomQuickSort需要随机选择划分index,这里为了简便,偷懒了,选择最后一个元素作为划分。
		if (p>=q)
		{
			return;
		}
		int r = piviotion(a,p,q);
		randomQuickSort(a,p,r-1);
		randomQuickSort(a,r+1,q);
	}

	int getBinaryInsertIndex(int*a,int p,int q,int ele){
		if (p<=q)
		{
			int k = (p+q)/2;
			int value = a[k];
			if (ele<value)
			{
				return getBinaryInsertIndex(a,p,k-1,value);
			}
			else if (ele>value)
			{
				return getBinaryInsertIndex(a,k+1,q,value);
			}else if (ele==value)
			{
				return k;
			}
		}

		return -1;
	}
	void binaryInsert(int*a,int p,int q,int ele){
		int index = getBinaryInsertIndex(a,p,q,ele);

		if (index==-1)
		{
			return;
		}
		else{
			for (int i=index;i<q;i++)
			{
				a[i+1] = a[i];
			}
			a[index]=ele;
		}
	}
	void findMinK(int*a,unsigned int num,unsigned int k){

		
		if (a==NULL)
		{
			return;
		}

		if (num==0||k==0)
		{
			return;
		}

		int *b = new int[k];

		// 将a的前k个元素拷贝进b,并对b进行排序(排序算法为klgk),此步骤共用时间O(k+klgk) = O(klgk)
		for (int i=0;i<k;i++)
		{
			b[i] = a[i];
		}
		randomQuickSort(b,0,k-1);

		//将a中剩下的n-k个元素插入到已经排好序的k个元素中,利用二分插入,此步骤共用时O((n-k)*lgk) = O(n*lgk)

		for (int i=k;i<num;i++)
		{
			binaryInsert(b,0,k-1,a[i]);
		}
		//打印数组b,用时O(k)

		for (int i=0;i<k;i++)
		{
			cout<<b[i]<<" ";
		}
		cout<<endl;

		//综上所述,时间复杂度为O(n*lgk)

	}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值