题目
输入一个长度为n的整型数组array,数组中的一个或连续多个整数组成一个子数组,找到一个具有最大和的连续子数组。
1.子数组是连续的,比如[1,3,5,7,9]的子数组有[1,3],[3,5,7]等等,但是[1,3,7]不是子数组
2.如果存在多个最大和的连续子数组,那么返回其中长度最长的,该题数据保证这个最长的只存在一个
3.该题定义的子数组的最小长度为1,不存在为空的子数组,即不存在[]是某个数组的子数组
4.返回的数组不计入空间复杂度计算
要求:时间复杂度O(n)O(n),空间复杂度O(n)O(n)
进阶:时间复杂度O(n)O(n),空间复杂度O(1)O(1)
思路
分治
代码
分治策略解法
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param array int整型vector
* @return int整型vector
*/
int FindMaxCrossingSubArray(vector<int>& array, int low, int mid, int high,
int& max_left, int& max_right)
{
int left_sum = -10000;
int sum = 0;
int right_sum = -10000;
int maxValue= 0;
for (int i = mid; i >= low; i--)
{
sum += array[i];
if (sum >= left_sum)
{
left_sum = sum;
max_left = i;
}
}
sum = 0;
for (int j = mid + 1; j <= high; j++)
{
sum += array[j];
if (sum >= right_sum)
{
right_sum = sum;
max_right = j;
}
}
maxValue = left_sum + right_sum;
return maxValue;
}
void FindMaximunSubarray(vector<int>& array, int low, int high, int& index_left
, int& index_right, int& maxValue)
{
int left_low = 0, left_high = 0, left_sum = 0;
int right_low = 0, right_high = 0, right_sum = 0;
int cross_low = 0, cross_high = 0, cross_sum = 0;
int mid = 0;
if (low == high)
{
index_left = low;
index_right = high;
maxValue = array[low];
}
else
{
mid = (low + high) / 2;
FindMaximunSubarray(array, low, mid, left_low, left_high, left_sum);
FindMaximunSubarray(array, mid+1, high, right_low, right_high, right_sum);
cross_sum = FindMaxCrossingSubArray(array, low, mid, high, cross_low, cross_high);
if (left_sum >= right_sum && left_sum >= cross_sum)
{
index_left = left_low;
index_right = left_high;
maxValue = left_sum;
if ((left_sum == right_sum) && (left_sum == cross_sum))
{
if (((left_high - left_low) < (right_high - right_low))
&& ((cross_high - cross_low) < (right_high - right_low)))
{
index_left = right_low;
index_right = right_high;
maxValue = right_sum;
}
if (((left_high - left_low) < (cross_high - cross_low))
&& ((right_high - right_low) < (cross_high - cross_low)))
{
index_left = cross_low;
index_right = cross_high;
maxValue = cross_sum;
}
}
else
{
if ((left_sum == right_sum) && ((left_high - left_low) < (right_high - right_low)))
{
index_left = right_low;
index_right = right_high;
maxValue = right_sum;
}
if ( (left_sum == cross_sum) && ((left_high - left_low) < (cross_high - cross_low)))
{
index_left = cross_low;
index_right = cross_high;
maxValue = cross_sum;
}
}
}
else if (right_sum >= left_sum && right_sum >= cross_sum)
{
index_left = right_low;
index_right = right_high;
maxValue = right_sum;
if ((right_sum == left_sum) && (right_sum == cross_sum))
{
if (((right_high - right_low) < (left_high - left_low))
&& ((cross_high - cross_low) < (left_high - left_low)))
{
index_left = left_low;
index_right = left_high;
maxValue = left_sum;
}
if (((right_high - right_low) < (cross_high - cross_low))
&& ((left_high - left_low) < (cross_high - cross_low)))
{
index_left = cross_low;
index_right = cross_high;
maxValue = cross_sum;
}
}
else
{
if ((right_sum == left_sum) && ((right_high - right_low) < (left_high - left_low)))
{
index_left = left_low;
index_right = left_high;
maxValue = left_sum;
}
if ( (right_sum == cross_sum) && ((right_high - right_low) < (cross_high - cross_low)))
{
index_left = cross_low;
index_right = cross_high;
maxValue = cross_sum;
}
}
}
else
{
index_left = cross_low;
index_right = cross_high;
maxValue = cross_sum;
}
}
}
vector<int> FindGreatestSumOfSubArray(vector<int>& array) {
// write code here
int left = 0, right = 0, sum = 0;
vector<int> MaxSubArray;
FindMaximunSubarray(array, 0, array.size() - 1, left, right, sum);
for (int i = left; i <= right; i++)
{
MaxSubArray.push_back(array[i]);
}
return MaxSubArray;
}
};