问题描述:
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素)。
分治策略求解方法:
假定要寻找数组A[low, high) 的最大子数组。将数组拆分为 两个子数组 A[low, mid), A[mid, high),那么A[low, high) 的任何连续子数组 A[i,j) 必然是以下三种情况之一:
- 完全位于子数组 A[low, mid)中,因此 low <= i <= j < mid
- 完全位于子数组A[mid, high)中,因此 mid <= i <= j <high
- 跨越中点,因此 low <=i < mid <= j < high
python代码:
def FindMaximumSubArray(A, start, end):
if end - start > 1:
mid = (start + end)/2
left_low_index, left_high_index, left_sum = FindMaximumSubArray(A, start, mid)
right_low_index, right_high_index, right_sum = FindMaximumSubArray(A, mid, end)
cross_low_index, cross_high_index, cross_sum = FindMaxCrossingSubArray(A, start, mid, end)
if left_sum >= right_sum and left_sum >= cross_sum:
return (left_low_index, left_high_index, left_sum)
elif right_sum >= left_sum and right_sum >= cross_sum:
return (right_low_index, right_high_index, right_sum)
else:
return (cross_low_index, cross_high_index, cross_sum)
else:
return (start, end, A[start])
def FindMaxCrossingSubArray(A, start, mid, end):
sum = 0
max_low_sum = A[mid - 1]
max_low_index = mid - 1
for i in range(mid - 1, start - 1):
sum += A[i]
if sum > max_low_sum:
max_low_sum = sum
max_low_index = i
sum = 0
max_high_sum = A[mid]
max_high_index = mid
for i in range(mid, end):
sum += A[i]
if sum > max_high_sum:
max_high_sum = sum
max_high_index = i
return (max_low_index, max_high_index, max_low_sum + max_high_sum)
A = [13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7]
print("low_index:%d, high_index:%d, sum:%d" % FindMaximumSubArray(A, 0, len(A)))
输出:
[Running] python -u "e:\GitHub\IntroductionToAlgorithms\Python\Chapter4\FindMaximumSubArray.py"
low_index:7, high_index:10, sum:43
[Done] exited with code=0 in 0.048 seconds
C++代码:
#include "FindMaximumSubArray.h"
#include <stdio.h>
using namespace std;
std::tuple<int, int, int> FindMaximumSubArray(int* a, int start, int end)
{
if (end - start > 1)
{
int mid = (start + end) / 2;
auto left = FindMaximumSubArray(a, start, mid);
auto right = FindMaximumSubArray(a, mid, end);
auto cross = FindMaxCrossingSubArray(a, start, mid, end);
if (get<2>(left) >= get<2>(right) && get<2>(left) >= get<2>(cross))
{
return left;
}
else if (get<2>(right) >= get<2>(left) && get<2>(right) >= get<2>(cross))
{
return right;
}
else
{
return cross;
}
}
else
{
return tuple<int, int, int>(start, end, a[start]);
}
}
std::tuple<int, int, int> FindMaxCrossingSubArray(int* a, int start, int mid, int end)
{
int max_low_sum = a[mid - 1];
int max_low_index = mid - 1;
int sum = 0;
for (int i = mid - 1; i >= 0; i--)
{
sum += a[i];
if (sum > max_low_sum)
{
max_low_sum = sum;
max_low_index = i;
}
}
int max_high_sum = a[mid];
int max_high_index = mid;
sum = 0;
for (int i = mid; i < end; i++)
{
sum += a[i];
if (sum > max_high_sum)
{
max_high_sum = sum;
max_high_index = i;
}
}
return tuple<int, int, int>(max_low_index, max_high_index, max_low_sum + max_high_sum);
}
void TestFindMaximumSubArray()
{
int a[] = { 13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7 };
int len = sizeof(a) / sizeof(int);
auto result = FindMaximumSubArray(a, 0, len);
printf("left_index:%d, right_index:%d, max_sum:%d\n", get<0>(result), get<1>(result), get<2>(result));
}
输出:
left_index:7, right_index:10, max_sum:43
E:\GitHub\IntroductionToAlgorithms\C++\build\Debug\IntroductionToAlgorithms.exe (进程 28460)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .