昨天我们说了寻找最大的K个数常规的两种解法,一种使用快速排序,另外一种是部分排序。今天我们介绍一种优化解法,
思想如下:在数组arr中我们进行一趟快速排序,选定key,把数组分为两部分a1,和a2。a1中的元素大于等于key,a2中的元素小于key。这样的话就会有两种可能,第一:a1中的元素个数小于K,所以a1中的元素加上K-a1.length个元素就是数组arr中最大的K个数。第二:a1中的元素个数大于或等于K,则返回a1中最大的K个数。这样不断递归就可以决绝这个问题。
先说说,一次快速排序。我们需要返回两个数组a1,a2,但是java不支持多参返回,所以我们用二维数组做为返回参数。具体代码如下: //
public static int[][] getArr(int[] arr) {
if (arr == null || arr.length == 0) {
return null;
}
int[][] newArr = new int[2][];
int key = arr[0];
List<Integer> list1 = new ArrayList<Integer>(); //首先使用list存储数据
List<Integer> list2 = new ArrayList<Integer>();
for (int i=1; i<arr.length; i++) {
if (arr[i] >= key) {
list1.add(arr[i]);
} else {
list2.add(arr[i]);
}
}
if (list1.size() < list2.size()) { //是数据存储更加均匀
list1.add(key);
} else {
list2.add(key);
}
int[] a1 = new int[list1.size()];//创建新的数组
for (int i=0; i<list1.size(); i++) {//数组赋值
a1[i] = list1.get(i);
}
int[] a2 = new int[list2.size()];
for (int i=0; i<list2.size(); i++) {
a2[i] = list2.get(i);
}
newArr[0] = a1;//储存大于等于key的元素
newArr[1] = a2;//存储小于key的元素
return newArr;
}
接下来我们就要递归调用了,代码如下,我们在外部声明一个list用来存储符合的数据,声明如下:
static List<Integer> list = new ArrayList<Integer>();
public static void xunzhao(int[] arr, int k) {
if (arr == null || arr.length == 0 || k < 0) {
return;
}
if (arr.length <= k) {//数据比K小
for (int i=0; i<arr.length; i++) {
list.add(arr[i]); //存储数据
}
return;
}
int[][] newArr = getArr(arr);
if (newArr[0].length >= k) { //a1的元素个数大于K,
xunzhao(newArr[0], k); //继续分解
} else {
for (int i=0; i<newArr[0].length; i++) {
list.add(newArr[0][i]); //存储元素
}
xunzhao(newArr[1], k-newArr[0].length); //在a2中获取K-a1.length个元素
}
}
原帖和源码下载地址
http://www.exceptionhelp.com/posts/540
分享到:
相关推荐
首先找到数组中第一个大于等于k的元素,然后在此元素之前的子数组中再寻找第k-1小的元素。这种方法适用于有序数组,时间复杂度为O(log n)。 6. **优先队列(堆)**:C++标准库提供了一个名为`<queue>`的头文件,...
如果是偶数,则中位数为中间两个数的平均值。 在本题中,我们有两个正序数组,这意味着数组中的元素已经按升序排列。寻找两个正序数组的中位数,我们可以采取以下策略: 1. **合并与排序**:最直观的方法是将两个...
在面对复杂问题时,优化设计的首要任务往往是寻找目标函数的最优解,即找到一组变量使得目标函数取得最小或最大值。为了实现这一点,一维搜索方法在优化计算中起着至关重要的作用。它不仅简化了高维问题的求解过程,...
PSO与K均值的结合,即基于K均值的PSO聚类算法,利用PSO的全局搜索能力来寻找K值的最佳分配,从而改进K均值的初始质心选择问题,提高聚类效果。 在这一过程中,微分方程组的数值解法也扮演着关键角色。在PSO中,粒子...
- **状态定义**:定义`g_k(i, S)`为从起点0出发,经过k个城市后到达城市i的最短距离,其中S表示已经访问过的k个城市组成的集合。 - **递推关系**:对于每个状态`g_k(i, S)`,可以通过以下递推公式计算: \[ g_k(i,...
14. **非线性优化**:寻找非线性函数的最大值或最小值。MATLAB的`fminunc`和`fmincon`函数适用。 15. **主成分分析(PCA)**:数据降维和特征提取。MATLAB的`pca`函数可实现。 16. **聚类分析**:将数据分组,如K-...
**问题描述**:在一个给定的网格中,从左上角到右下角寻找一条路径,使得路径上的数字之和最大。 **经典动态规划解法**: 设 `F[i]` 表示到达第 `i` 个格子的最大路径和,则有状态转移方程: \[ F[i] = \max\{F[j] ...
非线性规划问题通常涉及寻找一个变量向量,使得在一个非线性函数集合的约束下,目标函数达到最大值或最小值。在这种情况下,目标函数是分式的,即由分子和分母两部分组成,这增加了问题的复杂性。 解决这类问题的一...
目标函数**:定义了优化的目标,通常是寻找使目标函数达到最小(或最大)的设计方案。 #### 三、机械优化设计中的两类设计方法 **1. 优化准则法** 优化准则法通过定义一组特定的优化标准来指导设计过程,如最小...
最大子矩阵问题是一个在计算机科学领域内非常经典且重要的优化问题。它的主要目标是在一个给定的矩阵中寻找一个子矩阵,使得该子矩阵内的所有元素之和达到最大。这个问题可以被视为一维最大子序列和问题的一个自然...
无约束优化方法是数学优化领域中的一个重要分支,主要目标是在多维空间中寻找使目标函数达到最小值或最大值的点,而无需考虑任何限制条件。这类问题在工程、科学计算以及数据分析等领域广泛应用。本篇PPT教案主要...
这是一个贪心策略的问题,目标是在 1 到 N 的范围内找出三个数,使它们的最小公倍数最大化。Java 代码中,使用了一个 switch 语句来处理不同大小的 N,针对特定值给出最优解。然而,对于更一般的情况,可以考虑寻找...
问题的核心在于寻找一组\((i1, i2, j1, j2, k1, k2)\),使得这些小立方体内的整数之和达到最大。 #### 动态规划解法 在解决最大子长方体问题时,动态规划的关键在于识别并存储已解决的子问题结果,以备后续使用,...
对于有约束优化问题,常见的解决方法有直接解法和间接解法。其中,间接解法的一个重要分支就是惩罚函数法。惩罚函数法通过将有约束问题转化为一系列无约束问题,进而求解得到原问题的最优解。本文提出的“含脊优化...
对于K_2TSP问题,Christofides算法提供了一个有效的近似解法。Christofides算法最初用于解决标准的TSP问题,其核心思想是首先构建最小生成树,然后通过添加额外的边形成欧拉路径,最后通过所谓的“两阶段法”来修正...
3. **求可行域中整点个数**:在满足约束条件的点中,找出那些横纵坐标都是整数的点,即整点。这需要在可行域上逐步检查每个可能的整数坐标。 4. **求线性目标函数中参数的取值范围**:若目标函数z = x + ay (a > 0)...
在计算机科学与算法设计领域中,最大子矩阵和问题是寻找一个给定矩阵中具有最大和的子矩阵的问题。这类问题通常出现在数据挖掘、图像处理以及机器学习等领域,其解决思路与技术对提升算法效率具有重要意义。 #### ...