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
.
这是一道经典的题目,给定一个数组求和最大的子数组。算法导论对这道给出了两种解法,一种是分治策略,另一种是动态规划。
动态规划的解法是自底向上的方法,首先要找到题目的递推关系,这道题隐含了一个递推关系:pre=max(pre+nums[i],nums[i]),pre当前值下子数组和的最大值。
因而只要获取pre的最大值即可。C++实现如下。
int maxSubArray(vector<int>& nums) { int length=nums.size(); int i=0; int max=nums[0]; int pre=nums[0]; i++; while(i<length) { if(pre+nums[i]>nums[i]) pre=nums[i]+pre; else pre=nums[i]; if(max<pre) max=pre; i++; } return max; }
分治策略是将问题的规模不断的缩小,但问题本质不变。
这道题采用二分法,最大子数组可以在下列三种情况获得:
1、最大值在[left,mid-1]
2、最大值在[mid+1,right]
3、最大值跨越mid,需要计算mid之前的最大值以及之后的最大值,然后三者之和就是最大值
C++实现如下:
int maxSubArray(vector<int>& nums) { return divide(nums,0,nums.size()-1,INT_MIN); } int divide(vector<int>& nums,int low,int high,int tmax) { if(low>high) return INT_MIN; int mid=(low+high)/2; int lmax=divide(nums,low,mid-1,tmax); int hmax=divide(nums,mid+1,high,tmax); tmax=max(lmax,tmax); tmax=max(hmax,tmax); int lnum=0; int ltemp=0; for(int i=mid-1;i>=low;i--) { lnum+=nums[i]; if(lnum>ltemp) ltemp=lnum; } int hnum=0; int htemp=0; for(int i=mid+1;i<=high;i++) { hnum+=nums[i]; if(hnum>htemp) htemp=hnum; } return max(tmax,(htemp+ltemp+nums[mid])); }
时间: 2024-12-28 00:11:04