分治(Divide And Conquer)
分治,分而治之。先分后治
分治的一般步骤为:
- 将原问题分解成若干个规模比较小的子问题(子问题和原问题的结构一样,只是规模不一样)
- 子问题又不断分解成规模更小的子问题,直到不能再分解(直到可以轻易计算出子问题的解)
- 利用子问题的解推导出原问题的解
因此,分治策略非常适合用递归
需要注意的是:子问题之间是相互独立的

分治的应用:快速排序、归并排序、大数乘法
主定理
分治策略通常遵守一种通用模式:
解决规模为n的问题,分解成a个规模为n/b的子问题,然后在O(nd)时间内将子问题的解合并起来。
算法运算时间为:T(n) = aT(n/b) + O(nd),a>0,b>1,d>=0

比如,归并排序的运行时间是:T(n) = 2T(n/2) + O(n),套用上面的图表,则T(n) = O(nlogn)
问:为何使用分治策略后,性能会有所提升?
假如要排序n个数据
数据之间需要进行比较,假如两两比较,比如冒泡,需要n^2次
如果分为n/2
左边n/2两两比较,需要n/2*n/2 = n2/4
右边也是n2/4
左右加起来是n2/2
再合起来的时间为O(merge)。如果合并起来的时间小于n2/2,那么分治策略就是提升性能的。
最大连续子序列和
给定一个长度为n的整数序列,求它的最大连续子序列和
比如:-2,1,-3,4,-1,2,1,-5,4的最大连续子序列和为4 - 1 + 2 + 1 = 6
概念区分:
子序列可以不连续;
子串、子数组、子区间必须是连续的;
解法一:暴力法
穷举出所有可能的连续子序列,并计算出它们的和,最后取它们中的最大值。
package divide;
public class MaxSubValue {
public static void main(String[] args)
{
int[] array = {
-2, 1, -3, 4, -1, 2, 1, -5, 4};
System.out.println(maxSubArray(array));

本文介绍了分治策略的基本思想,包括其步骤和应用实例如快速排序、归并排序。针对最大连续子序列和问题,分别展示了暴力解法、优化后的暴力解法以及分治法的解决方案,最后分析了分治法如何提高性能。通过分治策略,将问题分解为子问题并递归求解,最终达到O(nlogn)的时间复杂度,优于暴力解法的O(n^2)和O(n^3)。
最低0.47元/天 解锁文章
1万+





