木槿花篱

嘻嘻,欢迎~

分治法 —— 最大子序和

原题:53. 最大子序和 (leetcode-cn.com)

题解:https://blog.csdn.net/weixin_44686373/article/details/107619930

给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

示例:

输入: [-2,1,-3,4,-1,2,1,-5,4]
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
进阶:

如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。

分治法就是把一个很复杂的问题划分成各个小的问题去解决,针对这道题,要想找最大子串和,看下图

 

 

 

最大值产生于红色部分, 绿色部分以及蓝色部分三者之间

如何求红色,绿色,蓝色三个part各自的最大值呢?

看图可知,每一个颜色的part都可以分解小规模问题。例如图中的红色part再可以分为红,绿,蓝三个part, 接着继续分继续分继续分 直到红色part和绿色part仅有一个元素时停止

大规模问题转化为小规模问题,最后每个小规模问题解合并即是大规模问题解
即是分治策略

代码:

 1 class Solution {
 2 public:
 3     int maxSubArray(vector<int>& nums) {
 4         return maxSub(nums,0,nums.size()-1);
 5     }
 6 
 7     int maxSub(vector<int>& nums,int left,int right){
 8         if(left == right) return nums[left];//当只有一个元素的时候
 9 
10         int mid = ( left + right ) / 2;//从中间分成两部分;
11 
12         int leftmax = maxSub(nums,left,mid);//计算左边子串最大和
13         int rightmax = maxSub(nums,mid+1,right);//计算右边子串最大和
14 
15         //计算中间的子串和
16         int left_midmax = INT_MIN;//先算左边最大(包含mid)
17         int left_midsum = 0;
18         for(int i = mid;i >= left; i--){
19             left_midsum+=nums[i];
20             if(left_midsum > left_midmax) left_midmax = left_midsum;
21         }
22         int right_midmax = INT_MIN;//右边最大(包含mid + 1 )
23         int right_midsum = 0;
24         for(int i = mid+1;i <=right; i++){
25             right_midsum+=nums[i];
26             if(right_midsum > right_midmax) right_midmax = right_midsum;
27         }
28         int midmax = right_midmax+left_midmax;
29 
30         return max(max(leftmax,rightmax),midmax);
31     }
32 };

在计算中间子串和的时候做一个小小的改变:

 1 //计算中间的子串和
 2         int midmax = INT_MIN;
 3         int midsum = 0;
 4         for(int i = mid;i >= left; i--){
 5             midsum+=nums[i];
 6             if(midsum > midmax) midmax = midsum;
 7         }
 8         if(midmax!=INT_MIN)midsum = midmax;
 9         for(int i = mid+1;i <=right; i++){
10             midsum+=nums[i];
11             if(midsum > midmax) midmax = midsum;
12         }

 

posted @ 2020-11-27 15:35  木槿花篱  阅读(314)  评论(0编辑  收藏  举报