算法第二章实践作业
1. 找第 k 小的数的分治算法
自然语言描述:
如果当前数组中只有一个元素,那么这个元素就是第 k 小的数,直接返回。
从当前数组中选择一个基准元素 p。
通过划分操作,将数组分成两部分:左边元素都不大于 p,右边元素都不小于 p,并确定 p 最终所在位置。
计算 p 在当前区间中的排名 rank。
如果 rank 等于 k,说明 pivot 就是第 k 小的数,返回 p。
如果 rank 大于 k,说明第 k 小的数在左半部分,递归在左半部分查找第 k 小的数。
如果 rank 小于 k,说明第 k 小的数在右半部分,递归在右半部分查找第 k - rank 小的数。
2. 最好时间复杂度和最坏时间复杂度
最好时间复杂度:O(n)
最好情况下,每次划分都比较均衡,基准元素大约把数组分成两半。此时每次递归只需处理约一半的元素,划分操作本身需要 O(n) 时间。
递推式为:
T(n) = T(n/2) + O(n)
根据主定理,该递推式的解为 O(n)。因此最好时间复杂度是 O(n)。
最坏时间复杂度:O(n²)
最坏情况下,每次选择的基准都是当前子数组中的最大值或最小值,导致划分极不均衡,每次递归只能减少一个元素。此时递推式为:
T(n) = T(n - 1) + O(n)
展开后为:
T(n) = O(n) + O(n - 1) + O(n - 2) + … + O(1) = O(n²)
因此最坏时间复杂度是 O(n²)。
3. 对分治法的体会和思考
通过本章学习,我对分治法有了更深的理解。分治法的基本思想是把一个复杂的大问题分解成若干个规模更小、结构相同的子问题,递归求解子问题,最后将子问题的解合并成原问题的解。
在找第 k 小的数这个问题中,分治法的优势很明显。它不需要对整个数组排序,而是通过一次划分判断第 k 小的数落在哪一部分,只递归处理包含答案的那一部分。这样比先排序再取第 k 个元素更高效。
同时我也认识到,分治法的效率很大程度上取决于划分是否均衡。如果每次划分都很不平衡,算法性能会明显下降。因此在实际应用中,可以通过随机选择基准、三数取中,或者使用“中位数的中位数”等方法来提高划分的稳定性。
总的来说,分治法不仅是一种算法设计方法,也是一种解决问题的思维方式。面对复杂问题时,先思考能否将其分解为更小、更相似的子问题,往往能让解题思路更清晰。

浙公网安备 33010602011771号