看完没收获来砍我。可以重点看,最剑指 Offer 40小的k个数(按照不同的实际情况采用不同的算法)

目录

题目:

1,排序算法,采用效率好的堆排序。

2,采用堆来计算。

3,特使要求下,灵活使用堆来解决实际问题。

(1)提出新的现实要求:如果现在由100亿个数据,我们要找出他的最小前100呢。

*****************如果采用方法2,不合理之处**********************

方法3:


题目:

 

1,排序算法,采用效率好的堆排序。

我们直接使用堆排序。

c语言的话,我们可以写一个向下调整算法,写一个堆排序算法。

int* getLeastNumbers(int* arr, int arrSize, int k, int* returnSize){
//用堆排序来做
HeapSort(arr,arrSize);
int* retArr=(int*)malloc(sizeof(int)*k);
for(int i=0;i<k;i++)
{
    retArr[i]=arr[i];
}
*returnSize=k;
return retArr;
  
}

 

2,采用堆来计算。

用c语言写的话,我们首先要写一个堆,或者写一个堆中要用到的部分:

时间复杂度;O(N+k*longN)

int* getLeastNumbers(int* arr, int arrSize, int k, int* returnSize){

//这里我们使用堆来做
HP ph;  //创建一个堆。
HeapInit(&ph,arr,arrSize);
int* retArr=(int *)malloc(sizeof(int)*k);  //调用完之后在外面释放
for(int i=0;i<k;i++)
{
    retArr[i]=HeapTop(&ph);
    HeapPop(&ph);
}
 *returnSize=k;  //注意这里的*号是一定要添加的,要先解引用。
 HeapDestroy(&ph);
 int* a=retArr;
 return retArr;
}

 

3,特使要求下,灵活使用堆来解决实际问题。

(1)提出新的现实要求:如果现在由100亿个数据,我们要找出他的最小前100呢。

*****************如果采用方法2,不合理之处**********************

这样我们如果用第二种的话,初始化要开辟一个大概40G的空间来存储着100亿个数据,这样空间复杂度太高了,我们消耗不起,当数据很大量时,方法2时不行的,无法解决问题。

估计以下100亿个整形要多大空间:

1KB=1024byte:

1M=1024kb;

1G=1024M:        1G  大约有 1024*1024*1024大约10亿个字节

100亿个整形  要100亿*4byte  字节

400亿除以10=40   

也就是说我们需要40G的空间来存放。   方法2不可以使用。

方法3:

(1)先把数组中前k个数据建成大堆

(2)然后用剩下的N-k个数与堆顶数据比较,比堆顶小的进行交换,重新向下调整调堆

时间复杂度:O(N*logk)  k比较小的。这个数不大,优秀算法。

空间复杂度:O(k)       很小,算法很省空间。优秀算法。

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
void Swap(int* px, int* py);
void AdjustDown(int* a, int n, int parent);
void Swap(int* px, int* py)
{
	int tmp = *px;
	*px = *py;
	*py = tmp;
}
void AdjustDown(int* a, int n, int parent)  
{
	int child = parent * 2 + 1;   
	while (child < n)  
	{
		
		if (child + 1 < n && a[child + 1] > a[child]) 
		{
			++child;            
		}
		if (a[child] > a[parent])
		{
			Swap(&a[child], &a[parent]);
			parent = child;    
			child = parent * 2 + 1;    
		}
		else
		{
			break;     
		}              
	}
}
int* getLeastNumbers(int* arr, int arrSize, int k, int* returnSize){
//用堆来做
if(k==0)
{
    *returnSize=0;
    return NULL;
}
if(k>=arrSize)
{
    *returnSize=k;
    return arr;
}
int*retArr=(int*)malloc(sizeof(int)*k);
//建堆:          前k个数建立 大堆:
for(int i=0;i<k;i++)  //取前k个数据准备建堆。
{
retArr[i]=arr[i];
}
for(int j=(k-1-1)/2;j>=0;j--) // 建堆
{
AdjustDown(retArr,k,j);
}
//剩下的N-k个数,与堆顶数据比较,比堆顶小,进堆
for(int i=k;i<arrSize;i++)
{
    if(arr[i]<retArr[0])
    {
        retArr[0]=arr[i];
        AdjustDown(retArr,k,0);
    }
    *returnSize=k;
}
return retArr;
}

 

  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LYH_1_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值