- 描述找第k小的数的分治算法(自然语言)
(1)选基准:从数组里随机挑一个数当作基准值(比如第一个或最后一个元素,比较好的是从第一个,中间那个和最后的选出数值大小居中的)。
(2)分区:把数组分成三部分,比基准小的(左区),等于基准的(中区),比基准大的(右区)。
(3)判断递归(直接返回):如果中区的下标等于k,那么中区值,即基准值,就是第k小数(直接返回)。如果不然,看第k小数落在哪个区,左区长度>=k,就去左区找第k小数,否则去右区找第k小的数(递归搜索)。
- 分析该算法的最好时间复杂度和最坏时间复杂度
(1)最好时间复杂度:O(n)。每次分区都能均分数组,且只遍历当前数组O(n),但递归只需走左/右区其中一块,递归层数仅logn,T(n)=n+n/2+n/4+...=O(n)。
(2)最坏时间复杂度:O(n^2)。每次选的基准是数组最值,分区仍遍历O(n),但递归要走n层(每层只排除 1 个最值元素),T(n)=n+(n-1)+(n-2)+...+1=O(n^2)。
- 结合本章的学习,谈谈你对分治法的体会和思考
分治法的核心是 “分而治之”,简而言之就是“拆大问题->解小问题->合并答案”,不过得保证拆出来的小问题和原问题是一个类型的。其次,并非所有问题都要复杂的合并步骤,比如找第k小数,分区后只需要递归一半,也不用合并左右结果,而像归并排序才需明确合并两个有序子数组。这说明分治法的关键是“分”,“治”要按实际需求操作。另外,拆分的策略决定了效率上限,失败的策略反而会增加复杂度。总而言之,对于复杂问题(如归并排序、汉诺塔),分治法能将逻辑拆解为 “拆分-求解-合并” 三步走,降低代码编写难度,便于理解和维护。
posted on
2025-10-24 13:01
paidaxing*
阅读(
3)
评论()
收藏
举报