最大子数组问题

GitHub

问题描述:

给定一个整数数组 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。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值