寻找N个数中最大的K个数,本质上就是寻找最大的K个数中最小的那个,也就是第K大的数。可以使用二分搜索的策略来寻找N个数中的第K大的数。对于一个给定的数p,可以在O(N)的时间复杂度内找出所有不小于p的数。寻找第k大的元素:
#include <iostream>using namespace std;//快速排序的划分函数int partition(int a[],int l,int r){ int i,j,x,temp; i = l; j = r+1; x = a[l]; //将>=x的元素换到左边区域 //将<=x的元素换到右边区域 while (1) { while(a[++i] > x); while(a[--j] < x); if(i >= j) break; temp = a[i]; a[i] = a[j]; a[j] = temp; } a[l] = a[j]; a[j] = x; return j;}//随机划分函数int random_partition(int a[],int l,int r){ int i = l+rand()%(r-l+1);//生产随机数 int temp = a[i]; a[i] = a[l]; a[l] = temp; return partition(a,l,r);//调用划分函数}//线性寻找第k大的数int random_select(int a[],int l,int r,int k){ int i,j; if (l == r) //递归结束 { return a[l]; } i = random_partition(a,l,r);//划分 j = i-l+1; if(k == j) //递归结束,找到第K大的数 return a[i]; if(k < j) { return random_select(a,l,i-1,k);//递归调用,在前面部分查找第K大的数 } else return random_select(a,i+1,r,k-j);//递归调用,在后面部分查找第K大的数}int main(){ int a[]={1,2,3,4,6,6,7,8,10,10}; cout<<random_select(a,0,9,1)<<endl; cout<<random_select(a,0,9,5)<<endl; return 0;}
如果所有N个数都是正整数,且它们的取值范围不太大,可以考虑申请空间,记录每个整数出现的次数,然后再从大到小取最大的K个。比如,所有整数都在(0, MAXN)区间中的话,利用一个数组count[MAXN]来记录每个整数出现的个数(count[i]表示整数i在所有整数中出现的个数)。只需要扫描一遍就可以得到count数组。然后,寻找第K大的元素:
for(sumCount = 0, v = MAXN-1; v >= 0; v--){ sumCount += count[v]; if(sumCount >= K) break;}return v;
极端情况下,如果N个整数各不相同,我们甚至只需要一个bit来存储这个整数是否存在(bit位为1或为0),这样使用的空间可以大大压缩。
当然也可以使用像计数排序、桶排序等这些以O(N)的时间排序算法也可以寻找第K大的数,但这也是以空间换时间为代价的。
实际情况下,并不一定保证所有元素都是正整数,且取值范围不太大。上面的方法仍然可以推广使用。如果N个数中最大的数Vmax,最小的Vmin,我们可以把这个区间[Vmax,Vmin]分成M块,每个小区间的跨度为d=(Vmax-Vmin)/M,即[Vmin,Vmin+d],[Vmin+d,Vmin+2d]......然后,扫描一遍所有元素,统计各个小区间中的元素个数,就可以知道第K大的元素在哪一个小区间。然后,再在那个小区间中找第K大的数(此时这个小区间中,第K大的数可能就是第T大的数了,这个T和每个小区间的个数有关)。我们需要找一个尽量大的M,但M的取值受到内存的限制。
寻找最大的K个数,使用堆实现,可以看这篇文章:http://blog.csdn.net/luxiaoxun/article/details/7796368
分享到:
相关推荐
### 寻找最大的K个数的关键知识点解析 #### 一、问题背景与基本思路 在IT面试场景中,“寻找最大的K个数”是一个常见的算法题目。该问题要求从大量无序数字中找到最大的K个数。这个问题看似简单,但实际上包含了多...
### 微软技术面试经典题目解析:寻找最大的K个数 #### 领域背景 在软件工程和技术面试领域,特别是在像微软这样的大型科技公司,面试官常常会提出一些算法和数据结构方面的问题来评估候选人的技术水平。这些面试题...
在Java编程中,寻找最大的K个数是一个常见的算法问题,主要出现在面试和数据结构与算法的练习中。这个问题要求从一个整数数组中找到最大的K个元素,而不仅仅是最大值。传统的解法通常包括排序整个数组,然后取前K个...
如果第k个元素比最大值小,更新最大值。接着,跳过k个元素,再比较第2k个元素,依此类推。直到遍历完整个数组,最后的最大值即为第k小元素。跳跃选择的平均时间复杂度为O(n),最坏情况下为O(n^2)。 4. 分治法: 将...
在Python编程中,高效地找出一个集合中最大的K个数或者最小的K个数是一个常见的需求。Python标准库提供了一个名为`heapq`的模块,它包含了一系列与堆相关的功能,能够有效地解决这类问题。本篇文章将详细讲解如何...
总之,有序矩阵中寻找第k小元素的问题是一个典型的优化问题,通过巧妙的算法设计,可以将原本可能需要O(n log n)时间的复杂任务降低到O(n),极大地提高了效率。Mirzaian和Arjomandi的贡献不仅在于他们的算法,更在于...
在这个问题中,我们要在数组中找到第k个最小的元素,同时考虑到数组中可能存在重复的元素。这个问题在实际应用中广泛出现,比如数据库查询优化、数据分析以及在线竞赛编程等场景。 在Visual C++环境下实现寻找第k小...
快速选择算法的时间复杂度在最坏情况下是O(n^2),但平均情况下的时间复杂度是O(n),因为它只对每次分区操作的一部分元素进行操作。此外,由于它不需要完全排序数组,所以空间效率相对较高,只需要常数级别的额外空间...
【部分内容】讨论了寻找最小k个数的几种方法,包括基于堆的实现和快速选择算法,特别是快速选择算法中的"五分化中项的中项"或"中位数的中位数"作为主元的选择策略,以确保在最坏情况下仍具有O(N)的时间复杂度。...
这个算法的时间复杂度在平均情况下是O(n),因为每次分区操作后,问题规模都会减半,直到找到目标元素。然而,在最坏的情况下(比如输入数组已经有序),时间复杂度会退化到O(n^2)。为了提高效率,可以通过随机化枢轴...
k优解通常出现在排序、选择问题或竞赛排名等场景,例如找到前k个最大或最小的元素。 描述虽然没有提供具体细节,但可以推测是关于如何有效地在一组数据中找出第k个最佳解的不同方法。 标签"ui"可能是指这些方法...
// 寻找满足整除3,并且末尾是0或者5的最大数 for (int i = len; i >= 1; i--) { if (a[i].rest == 0 || a[i].rest == 2) { cout [i].x; } } return; } ``` 算法复杂性分析: 该算法的时间复杂度主要体现在...
给定两个已排序数组 X 和 Y,每个数组长度均为 n,设计一个 O(log n) 时间复杂度的算法来找出这两个数组合并后的 2n 个数的中位数。 **算法设计:** 为了实现上述目标,可以通过以下步骤来设计算法: 1. **定义问题...
在这种情况下,可以考虑使用更高效的算法,例如快速选择算法,它是在快速排序的基础上修改而来,专门用于寻找数组中的第K小(大)元素,平均时间复杂度为O(n),但最坏情况下为O(n^2)。不过,对于这个问题,简单的...
这个问题的目标是从一个未排序或者部分排序的数组或集合中找到第k个最小的元素,其中k通常是一个正整数。这个问题在数据分析、数据库查询优化以及各种排序算法的实现中都有广泛的应用。 在解决这个问题时,可以使用...
这种算法的优势在于它可以在O(n log k)的时间复杂度内找到前k个最大元素,其中n是数组的长度。这是因为我们只对k个元素进行建堆操作,然后最多对n-k个元素进行一次比较和可能的堆调整。相比于直接排序整个数组,这在...
此外,补充的知识点提到了从N个数中选择k个数的组合问题,这个问题通常涉及到组合计数和深度优先搜索(DFS)。在不降序原则下进行DFS,可以保证在枚举过程中避免重复和混乱,使得解题过程更加清晰。这个原理在组合...
通过本文的学习,我们了解了如何使用快速排序的思想,在O(n)的时间复杂度内找到一个无序数组中的第K大元素。这种方法不仅理论基础扎实,而且实际应用广泛,对于提高算法理解和解决实际问题具有重要意义。在未来的...
寻找数组中的第K个最大元素,一个直观的方法是先对整个数组进行排序,然后返回第K个元素。Java中可以使用内置的`Arrays.sort()`方法实现快速排序、归并排序等。然而,这种方法的时间复杂度为O(n log n),对于大数据...
寻找数组中第k大的元素,基于快速排序思想,实践复杂度为O(n)