第二周作业
一、分治算法找第 k 小元素的描述(自然语言 + 伪代码)
该算法基于分治法思想,核心是通过 "分区" 操作将问题规模缩小,步骤如下:
- 从数组中选一个基准值(如最左侧元素),将数组分为两部分,即左半部分元素≤基准值,右半部分元素≥基准值,基准值位于最终位置pivotPos。
2.计算基准值在当前子数组中的排名currentRank(即左半部分元素个数,pivotPos - left + 1)。
3.分情况:
- 若currentRank == k,基准值就是第 k 小元素,直接返回。
- 若currentRank > k,第 k 小元素在左半部分,递归处理左子数组。
- 若currentRank < k,第 k 小元素在右半部分,递归处理右子数组(此时 k 需减去左半部分元素个数)。
function findKthSmallest(a, left, right, k):
    if left == right:
        return a[left]  // 子数组只有一个元素,即为目标
    
    pivotPos = partition(a, left, right)  // 分区并返回基准值位置
    currentRank = pivotPos - left + 1     // 基准值在当前子数组的排名
    
    if currentRank == k:
        return a[pivotPos]
    else if currentRank > k:
        return findKthSmallest(a, left, pivotPos-1, k)  // 左子数组找第k小
    else:
        return findKthSmallest(a, pivotPos+1, right, k - currentRank)  // 右子数组找第k-currentRank小
二、时间复杂度分析
最好时间复杂度:O (n)
每次分区操作能将数组均匀分为两部分(基准值恰好是当前子数组的中间元素)。第一次分区处理 n 个元素,第二次处理 n/2 个,第三次 n/4 个…… 总操作次数为n + n/2 + n/4 + ... + 1 ≈ 2n,因此时间复杂度为 O (n)。
最坏时间复杂度:O (n²)
每次分区后基准值是当前子数组的最大 / 最小元素(如数组已排序,选最左侧元素为基准)。第一次分区处理 n 个元素,第二次 n-1 个,第三次 n-2 个…… 总操作次数为n + (n-1) + (n-2) + ... + 1 = n(n+1)/2,因此时间复杂度为 O (n²)。
三、对分治法的体会和思考
总之,分治法的价值在于将复杂问题简单化,通过聚焦核心目标减少计算量,是算法设计中极具普适性的思想,也是理解更复杂算法(如动态规划)的基础。
 
                    
                
 
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号