[leetcode53]两种思路解决的Maximun Subarray

本文探讨了寻找整数数组中具有最大和的连续子数组的问题。通过动态规划与分治算法两种方法对比,详细解释了各自的实现过程及优缺点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    一、原题题干以及样例输出

Find the contiguous subarray within an array (containing at least one number) which has the largest sum. For example, given the array [-2,1,-3,4,-1,2,1,-5,4]the contiguous subarray [4,-1,2,1] has the largest sum = 6.

这道题题意非常清楚,对于一个给定的整数型数组,计算其中和最大的子数组并将和输出结果。第一反应是动态规划的算法,思路简单,实现起来也不复杂,可能也为评级为easy级别原因所在。由于这周刚学了分治算法的思想,将其与分治算法联系起来,发现并不如动态规划那么容易处理,但将思路理清后,也将其实现。现在把问题的两种解决思路以及代码阐释如下。

二、动态规划算法解决

动态规划算法的原理很简单,在一个循环的过程中,不断地比较新产生的值与原来的值大小,若符合要求,则更新新值,否则原值

保持不变或者作另外处理。当这种思想与这题结合起来时,实现就非常清晰。在一个循环中,将初始和设置为0,若然后不断向量中的

值相加,并将旧值付给另外变量存储。若新相加的和比原来的和要大,则将和更新为新产生的值,若相加的值比0要小,则将和初始化

为0。遍历向量中的每一个元素,直到最后选出所得最大值的和。其代码实现如下:

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int sum=nums[0];  
       int value=0;  
       if(nums[0]>0){  
           value=nums[0];     
       }  
       for(int i=1;i<nums.size();i++)  
       {  
           value+=nums[i];  
           if(value>sum){  
               sum=value;  
           }  
           if(value<0){  
               value=0;  
           }  
       }  
       return sum;  
    }
};
三、分治算法解决最大和问题

分治算法的一个主要思路就是将一个长向量分割为几个长度更小的向量,然后在范围更小的向量里面解决问题,如此循环,直

至向量的长度至最小,那么解决问题时也就显得非常轻松了。这种算法好处非常明显,在某些环境下可以很好的减少时间复杂度以

及空间复杂度。在此题的情况下,使用分治算法就显得略为复杂。

首先是明确思路,对于一个向量,我们将其分为两个部分,那么最终最大和数组所分布的情况只有三种,一种是全部在向量的

左半边,一种是完全在向量的右半边,还有一种是即在左半边又在右半边,第三种情况肯定会覆盖向量中的中位值。有了这个前提

后,我们就可以分别计算出这三种情况的最大值,三个最大值中最大的那个也就是我们所需要输出的那个了。第一种和第二种情况

比较好计算,直接从最左端和最右端开始即可,对于第三种情况,可以先从中间向左计算最大值以及中间向右计算最大值,两者相

加后则为第三种情况的值。

那么将一个向量进行循环递归,不断分割成小向量,然后在最终的小向量中按照上诉方法去计算三个值并比较将最大的值作为

输出结果返回即可,具体实现如下:

public class Solution {  
    public int maxSum(int[] A, int left, int right )  
    {  
        if( left == right ){  
            return A[left];  
        }  
        int center = (left + right) / 2;  
        int maxLeftSum  = maxSum( A, left, center);  
        int maxRightSum = maxSum( A, center+1, right);      
        int maxLeft = Integer.MIN_VALUE, tempLeft = 0;  
        int maxRight = Integer.MIN_VALUE, tempRight = 0;  
        for (int i=center; i>=left; --i){  
            tempLeft += A[i];  
            if (tempLeft > maxLeft){  
                maxLeft = tempLeft;  
            }  
        }  
        for (int i=center+1; i<=right; ++i){  
            tempRight += A[i];  
            if (tempRight > maxRight){  
                maxRight = tempRight;  
            }  
        }       
        int maxCenterSum = maxLeft + maxRight;        
        return maxCenterSum > maxLeftSum ? (maxCenterSum > maxRightSum ? maxCenterSum : maxRightSum) : maxLeftSum > maxRightSum ? maxLeftSum : maxRightSum;  
    }  
    public int maxSubArray(int[] A){  
        int len = A.length;  
        return maxSum(A,0,len-1);  
    }  
}  
四、个人总结

一般来说,分治算法解决问题大都会降低问题的时间复杂度,因为也受到非常广泛的欢迎。其核心就是将一个问题的解决范围

不断缩小,当范围缩小后,问题解决相对变得更加容易些,每一层递归所得到的结果都会为下一次递归做出贡献,这样循环下来,

直到问题解决,时间复杂度也就相应降低很多了。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值