算法复习——分而治之篇之次序选择问题
以下内容主要参考中国大学MOOC《算法设计与分析》,墙裂推荐希望入门算法的童鞋学习!
1. 问题背景
最小值查找:
-
例如给定数组 A [ 1..16 ] A[1..16] A[1..16],寻找其中最小值,如下图所示。
-
依次扫描,记录最小值
那么,对问题稍加改变,如何求得数组中第 k k k小的元素?
2. 问题定义
次序选择问题(Selection Problem)
输入:
- 包含 n n n个不同元素的数组 A [ 1.. n ] A[1..n] A[1..n]
- 整数 k ( 1 ≤ k ≤ n ) k(1\leq k \leq n) k(1≤k≤n)
输出:
- 数组 A [ 1.. n ] A[1..n] A[1..n]中第 k k k小的元素 ( 1 ≤ k ≤ n ) (1 \leq k \leq n) (1≤k≤n)
3. 排序求解
对数组排序,求得所有元素的次序,就很容易得到第 k k k小的元素,时间复杂度是 O ( n l o g n ) O(nlogn) O(nlogn)。
但这似乎不是最好的算法,因为我们只想要第 k k k小的元素;但是排序把所有第 k k k小的都得到了,这似乎是没有必要的,浪费了时间复杂度。
4. 问题分析
受启发于快速排序的数组划分。其中,我们的任务是用分界线分割数组,分界线左边的元素都比它小,右边的元素都比它大;但是,左边无需排序,右边也无需排序。
如果我们想求得的第 k k k个元素恰恰就落在分界线上,则直接获得结果;如果不能,就需要略作修改。
5. 固定位置划分求解
5.1 原理
- 选取固定位置主元,小于主元的元素个数 q − p q-p q−p
- 情况1: k = q − p + 1 k=q-p+1 k=q−p+1, A [ q ] A[q] A[q]为数组第 k k k小元素
- 情况2: k < q − p + 1 k < q-p + 1 k<q−p+1,在 A [ p . . q − 1 ] A[p..q-1] A[p..q−1]中寻找第 k k k小元素
- 情况3: k > q − p + 1 k > q - p + 1 k>q−p+1,在 A [ q + 1.. r ] A[q+1..r] A[q+1..r]中寻找第 k − ( q − p + 1 ) k-(q-p+1) k−(q−p+1)小元素
相比于其他分而治之的问题,在次序选择问题中,子问题始终唯一且无需合并问题解。
5.2 伪代码
固定位置划分:Partition(A, p, r)
输入:数组A,起始位置p,终止位置r
输出:划分位置q
x ← A[r]
i ← p - 1
for j ← p to r-1 dp
if A[j] <= x then
exchange A[i+1] with A[j]
i ← i + 1
end
end
exchange A[i+1] with A[r]
q ← i + 1
return q
固定位置次序选择:Selection(A, p, r, k)
输入:数组A,起始位置p,终止位置r,元素次序k
输出:第k小元素x
q ← Partition(A, p, r)
if k = (q - p + 1) then
x ← A[q]
end
if k < (q - p + 1) then
x ← Selection(A, p, q-1, k)
end
if k > (q - p + 1) then
x ← Selection(A, q+1, r, k-(q-p+1))
end
return x
5.3 时间复杂度分析
最好情况: T ( n ) = O ( n ) T(n)=O(n) T(n)=O(n)
最坏情况: T ( n ) = ∑ i = 1 n i ≤ n 2 = O ( n 2 ) T(n)=\sum_{i=1}^{n}i \leq n^2 = O(n^2) T(n)=∑i=1ni≤n2=O(n2),如下图所示。
6. 随机位置划分求解
6.1 伪代码
随机位置划分:Randomized-Partition(A, p, r)
输入:数组A,起始位置p,终止位置r
输出:划分位置q
s ← Random(p, r)
exchange A[s] with A[r]
q ← Partition(A, p, r)
return q
随机位置次序选择:Randomized-Selection(A, p, r, k)
输入:数组A,起始位置p,终止位置r,元素次序k
输出:第k小元素x
q ← Randomized-Partition(A, p, r)
if k = (q - p + 1) then
x ← A[q]
end
if k < (q - p + 1) then
x ← Randomized-Selection(A, p, q-1, k)
end
if k > (q - p + 1) then
x ← Randomized-Selection(A, q+1, r, k-(q-p+1))
end
return x
6.2 期望时间复杂度分析
使用代入法,可证明随机位置次序选择的期望时间复杂度是 O ( n ) O(n) O(n)。