分治算法寻找第K小数
来源:互联网 发布:dd linux命令复制磁盘 编辑:程序博客网 时间:2024/06/04 16:19
经典问题
有一道经典的算法题”Selection”
SELECTION
Input: A list of numbers S; an integer k
Output: The kth smallest element of S
For instance, if k = 1, the minimum of S is sought, whereas if k = |S|/2, it is the median.
这道题有很多解法,最简单的就是先对所有数排序。但是显然当数据较大时,这种方法效率不高。使用分治算法就可以在此基础上提高效率,因为只需对一部分而不是全部数据进行排序。
大致思路如下:每一次,先从数组中选出任意一个参考数pivot
。选取的方法几乎不会影响效率,一般来说随机选取即可。选取好pivot
后,对数组进行遍历,将所有数据分为三组,即小于,等于,大于pivot
的三组。例如:
若选取5作为参考数,则分成的三组为:
分组后,根据各组中数的数量,即可进行下一层递归,因此算法如下:
综上所述,可以得到其代码实现:
int findNumberK(vector<int> &vec, int k) { vector<int> s_vec, e_vec, l_vec; int pivot = vec[vec.size() / 2]; // 选取参考值 for (int i = 0; i < vec.size(); i++) { // 遍历并分组 if (vec[i] < pivot) { s_vec.push_back(vec[i]); } else if (vec[i] == pivot) { e_vec.push_back(vec[i]); } else { l_vec.push_back(vec[i]); } } if (k <= s_vec.size()) { // 进入下一层递归 return findNumberK(s_vec, k); } else if (k > s_vec.size() + e_vec.size()) { return findNumberK(l_vec, k - s_vec.size() - e_vec.size()); } else { return pivot; }}
这就是Selection问题的分治解法。LeetCode上有这么一道类似Selectiond的变种题目:
378. Kth Smallest Element in a Sorted Matrix
Given a n x n matrix where each of the rows and columns are sorted in ascending order, find the kth smallest element in the matrix.
Note that it is the kth smallest element in the sorted order, not the kth distinct element.Example:
matrix = [
[ 1, 5, 9],
[10, 11, 13],
[12, 13, 15]
],
k = 8,
return 13.Note:
You may assume k is always valid, 1 ≤ k ≤ n2.
这道题对比与Selection问题,所有在matrix中的数,更为“有序”,因为在其任何一列或任何一行上的数,都是有序的。因此在这里利用的是上题的思路,而由于这些数据在矩阵中是相对有序的,使用了二分查找的方法,就能较为高效地得到答案。这次采用的是非递归的方法。
基本思路是:每次遍历矩阵,得到小于或等于参考数median
的数量,以此决定下一次筛选的范围。代码实现如下:
class Solution {public: int findKthNumber(int m, int n, int k) { int small = 1, large = m * n; while (small < large) { int median = (small + large) / 2; int count = 0; // 遍历找出所有小于或等于median的数并计数 for (int row = 1; row <= m; row++) { if (row * n <= median) { count += n; } else { count += median / row; } } // 根据计数结果,进行下一步筛选 if (count < k) { small = median + 1; } else { large = median; } } return small; }};
- 分治算法寻找第K小数
- 分治算法--寻找第k大数
- LeetCode4. Median of Two Sorted Arrays(寻找第k小数:分治O(log(n+m)))
- 快排、寻找第k小数和前k小数
- 分治法 寻找第K小元素
- 分治-寻找第k小的数
- 分治法实验-寻找第k小元素
- 寻找无序数组的第K项(分治)
- 007-寻找第k小元素-分治法-《算法设计技巧与分析》M.H.A学习笔记
- 算法:寻找第K小元素
- 算法题/寻找第K大数
- 【算法题】寻找第K个丑数
- 分治算法寻找硬币
- 第k小数
- 第K小数
- 第k小数
- 第k小数
- whuoj1574 第K小数
- 915
- git的基本操作
- html5实现最简单的文件下载
- Jsoup解析html
- 327. Count of Range Sum
- 分治算法寻找第K小数
- 原生js实现单面应用程序spa
- DB2和Oracle区别
- Eclipse/IDEA快捷键
- Linux 文件相关命令
- 机器学习(1)-KNN算法理解
- 2989:糖果(2.6基本算法之动态规划)
- 存储类型、ADT、纯C去引用、算法及设计原则、时间复杂度---基本概念
- mybatis_study03