
[分治] 找到最大子序和
思路:
- 定义函数find_max_val(arr,low,right)为:找到数组arr区间为[low,right]之间的最大连续子序和;
- 分治法,以mid为轴,分为左右两个区间[low,mid],[mid+1,right],并分别找两个区间各自的最大连续子序和
- 但Step2并没有真正囊括所有连续子集,最后一步还需要找到交叉连续子集: 以mid为轴点分别向两边扩展,并记录最大交叉子序和
代码:
#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;
int find_crossing_max_val(vector<int>& A,int low,int mid,int high)
{
int leftsum = -0x3f3f3f;
int rightsum = -0x3f3f3f;
int sum =0;
for(int i =mid;i>=low;i--)
{
sum += A[i];
if(sum > leftsum)
{
leftsum =sum;
}
}
sum=0;
for(int i =mid+1;i<=high;i++)
{
sum += A[i];
if(sum > rightsum)
{
rightsum =sum;
}
}
return leftsum+rightsum;
}
int find_max_val(vector<int> & A,int low,int high)
{
if(low == high) return A[low];
int mid = (low+high) /2;
int max0 = 0;
int leftmax = find_max_val(A,low,mid);
int rightmax = find_max_val(A,mid+1,high);
int crossingmax = find_crossing_max_val(A,low,mid,high);
if(leftmax>rightmax && leftmax > crossingmax) max0 =leftmax;
if(rightmax>leftmax && rightmax > crossingmax) max0 =rightmax;
if(crossingmax>leftmax && crossingmax >rightmax) max0 = crossingmax;
return max0;
}
时间复杂度 : O(logn * n )