分治策略

   1.分治策略

       分治 策略,从字面上也能看出,是将原有问题分解,使其具有更小的规模,从最小规模向上层层递归并返回 ,最终解决问题。分治策略应用于求股票最大利润问题、矩阵乘法等一系列问题。对于这些已经解决 的问题,我想说这虽然很重要,但是不是最重要的,重要的你要学会分治的思想,然后利用这些思想去解决新的问题,去设计算法,寻找更优的算法,更少的时间复杂度。递归的时间复杂度一般都与lgn有关系,分治一般都是平分原来问题的规模,这样才能使递归树的层数最少。

   递归:分治一般是平分,可以减少运行时间,而递归不一定部分,当嵌套循环较多时,可以使用递归,只在递归中写上一个递归(循环)结束的条件即可。

先来说一下求解递归问题的步骤:分解 、解决、合并。这几个字应该是分治的核心了。

    分解:将原来的问题分解成多个子问题(一般是平分),子问题的形状要求的东西全   和原问题一样。注意:谨慎处理边界问题,中位数mid,是给右子数组还是左子数组,有时候只是比较一下,然后就把它舍弃了,比如折半查找。注意:绝对不可能每个子问题都包含mid,会无限递归,比如只剩下(0,1)两个位置元素时。此时就要看将mid给谁能把所有的情况都包括。最大子数组问题就能很好的说明这个问题。

    解决:递归的求解子问题。看清那些是和原来问题一样,需要递归的(调用自身),还有一些子情况,可能不是递归的。只要子问题足够小就停止递归,直接解决。

    合并:假设当子问题都解决了,合并为最终结果。有时只是简单地一个return或者将所有子问题的一个整合。

2.最大子数组

       实际问题:根据股票每天的价格如何求解,怎样购买才能利润最大,利润最大就要买进和卖出的差价最大,可以把相邻元素的的价格差写成一个数组,进行分析,也就是最大子数组问题。

       我们一般人,通常会想到使用暴力的发发找出所有的子数组,然后比较。这样的时间复杂度为:n的平方,但是使用分治,就能把问题优化成nlgn;注意 :分解子数组时 把mid元素分给左边数组,与求交叉状态时的最大子数组时的(可以简单地记成:哪一半子数组拥有mid哪一半子数组就要在sum上加上mid元素进行比较,但是不能两边都加,会重复求和)

for(int j=mid+1;j<=high;j++)中的j的初始值是对应的,因为要包含所有的情况
<img src="https://img-blog.csdn.net/20141021162635656?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamlhb21pbmdsaWFuZw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
,还有两种临界情况只含有左边部分到mid,和只含有mid到右边部分,把mid分到做子数组包含了第一种临界情况,交叉情况包含了:第二种临界情况。这样上图:a的分法就包含了所有的情况。

      因为暴力求解在解决n较小的时候还是有很多优势的,所以能否可以将最小子数组的分治求解,在子问题规模小于某个规模的时候使用暴力求解。

/**
	 * 最大子数组的暴力求解方法:找出所有的子数组进行判断,注意子数组只有一个元素时,也要进行
	 * 一次是否为当前最大值的比较。
	 */
	public int [] vioMaxSunArray(int a[],int low,int high)
	{
		int result[]=new int [3];
		result[2]=-1000;
		for(int i=low;i<=h
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值