【算法】快速排序/数组第K小的元素
快速排序
和归并排序一样,也是采用分治(Divide and Conquer)思想。分为三步:
分解:将数组A[p...q]划分成两个数组A[p..r-1]和A[r+1..q],使得A[p..r-1]中的每个元素都小于等于A[r],并且A[r+1..q]中所有元素大于等于A[r],A[r]称为主元。
解决:递归调用快速排序,对两个子数组进行排序
合并:不需要合并操作,子数组采用原址排序,已经有序。
和归并排序相比,归并排序主要工作在于合并操作,而快速排序在于划分。划分数组的过程如下描述
PARTITION(A,p,q)x = A[p]i = p;for j = p+1 to qif A[j] <= xi = i+1exchange A[i] A[j]exchange A[p] A[i]
详细的划分过程如图所示
经过一次partition划分,分成两个数组A[p..r-1]和A[r+1..q],使得A[p..r-1]中的每个元素都小于等于A[r],并且A[r+1..q]中所有元素大于等于A[r],r为partition的返回值
将数组A进行划分的关键代码
private int partition(int[] a, int p, int q) {int i = p, j = p + 1;while (j <= q) {if (a[j] <= a[p]) {i++;swap(a, i, j);}j++;}swap(a, i, p);return i;}
于是,快速排序的算法描述为
public static void quickSort(int[] a, int p, int q) {if (p < q) {int r = partition(a, p, q);quickSort(a, p, r - 1);quickSort(a, r + 1, q);}}
快速排序的性能:
快速排序在再坏情况下,运气实在糟透了,每次都出现不平等的划分,将其划分成了1个元素和n-1个元素,于是有T(n)=T(n-1)+T(1)+θ(n),则:T(n)=O(n^2)
最好情况下,我们假设每次划分都是平等划分,即T(n)=2T(n/2)+θ(n),于是T(n)=O(nlgn).
可以证明,只要是常数比例的划分,算法的运行时间都是T(n)=O(nlgn)。因此,快速排序的平均运行时间更接近于其最好情况而不是最坏情况。
为了保证每次划分出现常数比例的划分,在算法中引入随机性。
private int randomPartition(int[] a, int p, int q) {int i = (int) (Math.random() * (q - p) + p);swap(a, p, i);return partition(a, p, q);}
可以证明,快速排序的期望运行时间为T(n)=O(nlgn),最坏运行时间为T(n)=O(n^2)
同时,快速排序也是不稳定的排序算法,例如A=[2,3,1,2],经过第一次划分后,划分为[2,1,2,3],这时的r位于下标2处,且与A中的两个2的顺序相比已经交换过一次了。两个2逆序。
关于找数组第k小的数
其实没看算法的时候我觉得需要排序,然后可以在O(1)的时间里面找到第k小的数,学习了算法就不能犯这样的错误啦,常用的好的排序算法比如快速排序,它的时间复杂度为O(nlogn)。事实上我们可以在O(n)的时间内找到数组的第k小的元素。
答案就在上面讲的快速排序中,事实上,在上面的快速排序的划分过程中其实已经产生了第K小的数。
可以参考下图所示
获得数组第k小的数的关键代码
public static int getKthValue(int[] a, int p, int q, int k) {if (p == q) return a[p];int r = randomPartition(a, p, q);int i = r - p + 1;// r是当前序列里面第i小的数字if (i == k) {return a[r];} else if (k < i) {return getKthValue(a,p,r-1,k);} else return getKthValue(a,r+1,q,k - i);}
这种算法的时间复杂度可以达到期望为线性。E[T(n)]=O(n)
转载于:https://www.cnblogs.com/qhyuan1992/p/5385285.html
【算法】快速排序/数组第K小的元素相关推荐
- 二分、数组-LeetCode378. 有序矩阵中第K小的元素
1.题目描述 https://leetcode-cn.com/problems/kth-smallest-element-in-a-sorted-matrix/ 给定一个 n x n 矩阵,其中每行和 ...
- C语言寻找第k小元素,小技巧——查找第k小的元素
今天分享一个小技巧,虽然是小技巧但是还是很有价值的,曾经是微软的面试题.题目是这样的,一个无序的数组让你找出第k小的元素,我当时看到这道题的时候也像很多人一样都是按普通的思维,先排序在去第K个,但是当 ...
- python第k序列元素查找_Python寻找第k小的元素
更多: http://my.oschina.net/u/438371/blog/131956 1.[代码][Python]代码 # -*- coding: utf-8 -*- from random ...
- 378、有序矩阵中第K小的元素
题目:给定一个 n x n 矩阵,其中每行和每列元素均按升序排序,找到矩阵中第 k 小的元素 归并排序 思路及算法 由题目给出的性质可知,这个矩阵的每一行均为一个有序数组.问题即转化为从这 n 个 ...
- 记录:2022-9-30 打家劫舍 二叉搜索树中第K小的元素 公平锁 磁盘调度
学习时间:2022-9-30 学习内容 1.LeetCode 198. 打家劫舍 思路 dp[i] = dp[i-1]之前的最大值 + num[i] 优化思路:把最大值用一个变量来存 代码 class ...
- 【LeetCode】230#二叉搜索树中第K小的元素
题目描述 给定一个二叉搜索树,编写一个函数 kthSmallest 来查找其中第 k 个最小的元素. 说明: 你可以假设 k 总是有效的,1 ≤ k ≤ 二叉搜索树元素个数. 示例 1: 输入: ro ...
- [leetcode] 230. Kth Smallest Element in a BST 找出二叉搜索树中的第k小的元素
题目大意 https://leetcode.com/problems/kth-smallest-element-in-a-bst/description/ 230. Kth Smallest Elem ...
- LeetCode每日训练2—有序矩阵中第K小的元素(7.2)
题目描述 给定一个 n x n 矩阵,其中每行和每列元素均按升序排序,找到矩阵中第 k 小的元素. 请注意,它是排序后的第 k 小元素,而不是第 k 个不同的元素. 示例: matrix = [ [ ...
- 378. Kth Smallest Element in a Sorted Matrix 有序矩阵中第K小的元素
Title 给定一个 n x n 矩阵,其中每行和每列元素均按升序排序,找到矩阵中第 k 小的元素. 请注意,它是排序后的第 k 小元素,而不是第 k 个不同的元素. 示例: matrix = [ [ ...
最新文章
- python调用gitlab api自动合并分支_Python3 如何使用 GitLab API 进行批量的合并分支
- matlab中画花瓣,matlab画心,画玫瑰花,表白合集
- boost::exception模块实现boost :: tuple捆绑的测试程序
- CentOS5.6 安装RabbitMQ
- 阿里巴巴对Java编程【安全规约】的规约
- mysql pdo 读取字段名_PDO如何处理SQL语句中对字段名以及表名的转义
- $provide.decorator
- java更改安卓图标_java – 一个按钮的Android背景文本图标
- 网口压线顺序_RJ45水晶头排线顺序
- DZone每日必读-news: 指导软件团队取得成功的 4 种方法
- 大数据在各领域应用之精准营销
- ZZULIOJ1096-1100Python解法
- Java、JSP通用SQL查询分析器
- LNZ32P4-C - Pan-Tilt-Zoom (PTZ) Camera with 1080p HD Video Color Night Vision
- linux下载pip
- 第一段代码 打开了新世界的大门
- CRNN端到端文本识别复现实践
- 学好小学奥数必懂的解题思路 建议家长帮孩子收藏
- 21秋期末考试公共经济学10834k1
- codevs 1060 搞笑世界杯