这道题的本质是求连续最大子区间问题,将数组中的每个元素转换为与前一位的差,那么最大的子区间就是收益最高的区间。
在求最大子区间时,可以想到,如果将区间分为两部分,那么最大子区间可能是左边区间的子区间,右边区间的子区间,也可能跨越中点的区间。对于左右子区间,可以很容易转化为递归步,所以只需要计算跨越中点的最大区间,这个很简单:从中点开始往左往右加,若更大,则更新区间端点,否则继续加。
intfind_max_subarray(vector<int>& a, int low, int high)
{
if (low == high)
{ if(a[low] < 0)
return 0;
else
return a[low];}
else
{
int mid = (low + high) / 2;
int left_max = find_max_subarray(a, low,mid);
int right_max = find_max_subarray(a,mid+1, high);
int sum = 0, left = mid, t1 = a[mid];
for (int i = left; i >= low; i--)
{
sum += a[i];
if (sum > t1)
{
t1 = sum;
left = i;
}
}
int right = mid + 1, t2 = a[right];
sum = 0;
for (int i = right; i <= high; i++)
{
sum += a[i];
if (sum > t2)
{
t2 = sum;
right= i;
}
}
int cross_max = t1 + t2;
if (left_max < 0 && right_max< 0 && cross_max < 0)
return 0;
if (left_max >=cross_max&&left_max >= right_max)
return left_max;
else if (right_max >= cross_max)
return right_max;
else
return cross_max;
}
}
classSolution {
public:
int maxProfit(vector<int>&prices) {
int n = prices.size();
if (n<2)
return 0;
for (int i = n - 1; i > 0; --i)
prices[i] -= prices[i - 1];
return find_max_subarray(prices, 1, n - 1);
}
};