分治法——经典题型算法思路

求一个整数序列中的最大和最小元素

算法思想:

本题为无序序列查找最大/最小元素位置问题。

要求采用分治法求解,则与称假币问题的思路类似。

思路:(以查找最大元素为例)

对arr[low…high]求最大值max0

并分为arr[low…mid0]、arr[mid0+1…high]左右两段

再对分别对arr[low…mid0]和arr[mid0+1…high]求最大值max1L,max1R

每次将一段大区域划分为小区域

并在两个小区域中找到最大值与原来区域最大值相同的区域

,接着划分,递归上面过程,

由于partition过程不断缩小搜索范围,总能找到最大值所在位置。

检查最大值在左半段还是右半段中,若在左半段中

继续对左半段进行二分,分成两个更小的半段,求max2L,和max2R

检查最大值在小左半段还是小右半段,若在小左半段中

则继续对小左半段进行二分。。。

重复以上步骤,直至含有最大值的一段无法再分(只有一个元素),则该元素就是最大值,则该元素所在位置便是所求位置。


使用分治法实现归并排序

算法思想:

归并排序是分治法的经典案例,基本思想是将整体问题转换为局部问题,将局部问题的解最终合成整体解。

归并排序将序列分割为各个单元素:

例如:

[3  1  2  6  5  7  9]

划分为:

[3] [1] [2] [6] [5] [7] [9]

选取2个为一组对元素进行合并、排序(在此选2为合并的个数)

[3 1]  [2 6]  [5 7]  [9]

重复以上过程直至合成为一个序列

再次合并,排序(下面将合并排序整合为一步)

[1 2 3 6] [5 7 9]

再次进行合并,排序

[1 2 3 5 6 7 9]

当重新合并为一个序列时,序列已经变成有序序列。

从整体—>局部—>整体的这种解题方法就是分治法

归并排序使用自下而上的分治法,也可以使用自上而下的快速排序对序列进行排序。


使用分治法实现快速排序

简述:

常见的快排有3种类型

1.二分快排:

以序列的最后一个数num做划分值,将≤num的元素放左侧,>num的元素放在右侧,

再将>num的第一个元素与划分值位置交换,使得左侧区域扩充一个元素,

且该元素位置被固定下来。

取左侧区域的最后一个元素(num之前的元素)与右侧区域的最后一个元素

分别作为划分值对两个区域接着划分,重复这样的递归过程。

对于划分区域来说每次划分都会固定一个元素,

左右分区做递归, partition下去,总会让序列彻底有序。

2.三分快排:

与二分快排类似,选最后一个值num作为划分值将序列分为,<num,=num,>num三个区域,

分完后将>num区域的第一个元素与num交换,

导致中间全为num,中间的值就固定下来,

每次递归都会固定下来至少一个数

再对<num,>num区域重复partition过程,总会能使得序列有序。

三分快排比二分快排稍快,它一次可以排多个元素。

但无论上面两个的哪一种排序,时间复杂度都是O(n^2)

,因为划分值的位置是人为选取的,

因此总能举出最差的例子(1,2,3,4,5,6,7,8,9,10)

该序列每次partition只解决一个数。时间复杂度O(n^2)

3.随机划分值快排:

利用随机数取划分值,使得时间复杂度接近O(n*logN)

(该时间复杂度由概率论中,由于浮点数分布被认为是连续分布,单个点对整体影响可忽略,由期望和的累加公式求得,长期期望。算出每种情况的出现的概率以及对应的时间复杂度做积,相加,最终结果就是nlogN)


分治法求解最大子段和

分治法求最大子段和:

将整个大数列分为左右两个部分:则最大连续子数列应该在以下3种情况中

  1. 完全包含在左半部分的数列中
  2. 完全包含在右半部分的数列中
  3. 横跨分割点,左右各占一部分

第1,2种情况可利用递归,不断对整个数列进行partition得到结果。

而第3种情况依赖于第1,2种情况,因此递归会从高—>低  在算出最底层第一二种情况后 再从低—>高 回推给上层,算出第三种情况的结果,三种情况取最大值,就是本题的解


使用分治法对递增有序序列a求众数

分治法求众数类似于荷兰国旗问题,而此序列已经有序

因此,只需要找到中间值,

与中间值相等的数为一个区域,<中间值的为一个区域,>中间值的为一个区域,

将序列划分为3部分<mid,=mid,>mid,

记录=mid区域中元素值个数max,

并在递归过程中不断更新max

继续对<mid,>mid区域递归上述过程,直到区域划分为1或0。

最终max的最大值就是整个序列的众数。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值