我们知道,快排第一步是选取一个数组中的确定数,比如最右侧元素
n
u
m
s
[
r
i
g
h
t
]
nums[right]
nums[right],所有小于
n
u
m
s
[
r
i
g
h
t
]
nums[right]
nums[right]的,放在它左边;大于
n
u
m
s
[
r
i
g
h
t
]
nums[right]
nums[right]的,放在它右边。这样我们就唯一确定了
n
u
m
s
[
r
i
g
h
t
]
nums[right]
nums[right]的下标。
快选只关心当前
n
u
m
s
[
r
i
g
h
t
]
nums[right]
nums[right]的下标
q
q
q和目标
i
n
d
e
x
index
index的大小,
i
n
d
e
x
=
n
u
m
s
S
i
z
e
−
k
index=numsSize-k
index=numsSize−k,如果
q
q
q<
i
n
d
e
x
index
index就去
[
q
+
1
,
r
i
g
h
t
]
[q+1,right]
[q+1,right]递归分治。分治结束,
n
u
m
s
nums
nums的倒数第
k
k
k个数,即为所求。
快选和快排的分治
p
a
r
t
i
t
i
o
n
partition
partition实现是一样的,区别在于,快排递归到了数组的最细粒度,即双元素排序,乃至单元素排序。
随机分治是一种分治策略,使得快选的平均时间复杂度在数学证明上趋于线性时间。
四、代码分析
理解思路很重要!
博主欢迎读者在评论区留言,作为日更博主,看到就会回复的。
五、AC
六、复杂度分析
时间复杂度:
O
(
n
)
O(n)
O(n) ,
n
n
n是
n
u
m
s
nums
nums数组的大小。快选
n
u
m
s
nums
nums的平均时间复杂度是
O
(
n
)
O(n)
O(n),算法导论有严格的数学证明,追求所以然的同学看书学习嗷。
空间复杂度:
O
(
l
o
g
n
)
O(logn)
O(logn),递归调用函数占用了栈空间,递归的空间复杂度是
O
(
l
o
g
n
)
O(logn)
O(logn)。