【编程之美】2.15 子数组之和的最大值(二维)

思路,有了一维的思路,我们想办法把二维问题转化为一维的问题。

我们假定已经选中了行的范围是 a-c 那么把每一列中 a-c的元素加起来就变成了一个一维的问题。只需对行的范围遍历,再用一维的方法来解就可以了。

注意,也可以对列的范围遍历,行和列那个小就对哪个遍历。 复杂度为O(M * N * min(M, N))

#include <stdio.h>
#include <stdlib.h>

void getSumCol(int * a, int aColNum, int RowBegin, int RowEnd, int * SumColArray)
{
    for(int j = 0; j < aColNum; j++)
    {
        SumColArray[j] = 0;
        for(int i = RowBegin; i <= RowEnd; i++)
        {
            SumColArray[j] += *(a + i * aColNum + j);
        }
    }
}

int getMax2DArraySum(int * a,const int aRowNum,const int aColNum)
{
    int MaxSum = a[0];
    int Sum = 0;
    int * SumColArray = (int *)calloc(aColNum, sizeof(a[0]));
    for(int i = 0; i < aRowNum; i++)
    {
        for(int k = i; k < aRowNum; k++)
        {
            getSumCol(a, aColNum, i, k, SumColArray);

            Sum = SumColArray[0];
            for(int j = 1; j < aColNum; j++)
            {
                Sum = (Sum > 0) ? Sum + SumColArray[j] : SumColArray[j];
                MaxSum = (Sum > MaxSum) ? Sum : MaxSum;
            }
        }
    }
    free(SumColArray);

    return MaxSum;
}

int main()
{
    int a[4][5] = {
        { 1, 2, 3, 4, 5},
        {-3,-5, 3,-8, 0},
        { 2, 3, 5, 6, 8},
        { -3,1, 2, 3, 0}
    };

    int max = getMax2DArraySum((int*)a, 4, 5);

    return 0;
}
时间: 2024-10-08 14:48:18

【编程之美】2.15 子数组之和的最大值(二维)的相关文章

数字之魅:子数组之和的最大值[二维]+[三维]

题目:如何求出一个二维数组中的最大子数组之和. 方案一:暴力破解-枚举法.对于一个二维数组我们列举出每一个子数组值的大小,然后进行比较,这样就可以得到最大的和了.其时间复杂度为:O(N*N*M*M*Sum的时间复杂度)[N表示行数,M表示列数,Sum是求解子矩阵的和].由于Sum函数求和也是采用循环,足见这个时间复杂度可是相当的大. 方案二:先计算出以左上角的元素(1,1)和当前元素(i,j)为顶点对的子矩阵的部分和,部分和的计算如下图(一)所示,我们可以看出:以(i_min,j_min),(i

2.15 子数组之和的最大值(二维)

题目:给定一个二维数组,求这个二维数组的子数组之和的最大值. 分析:将二维降低到一维的情况. 代码: #include <iostream> const int MAXN = 10000; const int INF = 100000000; using namespace std; int B[MAXN][MAXN], PS[MAXN][MAXN]; int n, m; int BC(int first, int last, int liehao) { return PS[last][lie

编程之美读书笔记2.15 - 子数组之和的最大值(二维)

http://blog.csdn.net/pipisorry/article/details/39083073 问题: 求二维数组(矩阵)的子矩阵之和的最大值. 亦可见:http://poj.org/problem?id=1050 解法1:(解释见注释) 每个子矩阵由列长.行长和左上角的元素位置决定.如果我们指定左上角的元素位置 (i,j) 和列长 c,那么可以求所有这些子矩阵中和最大的.然后,变化列长 c,可以求以 (i,j) 为左上角的最大和子矩阵.最所有左上角位置再求最大和子矩阵,问题就解

编程之美之2.14 求数组的子数组之和的最大值

[题目] 一个有N个整数元素的一维数组(A[0],A[1],A[2],...A[n-1]),这个数组中当然有很多子数组,那么子数组之和的最大值是多少? 该子数组是连续的. 我们先来明确一下题意: (1)子数组意味着是连续的. (2)题目只需要求和,并不需要返回子数组的具体位置. (3)数组的元素是整数,所以数组可能包含正整数,负整数或者零. 举几个例子: 数组:[1,-2,3,5,-3,2]返回8 数组:[0,-2,3,5,-1,2]返回9 数组:[-9,-2,-3,-5,-3]返回8 [解法一

[编程之美] 2.14 求数组的子数组之和的最大值

问题描述:给定一个包含N个整数的数组,求数组的子数组之和的最大值. 这是递归和贪心策略的一个经典问题.现在,对这个问题进行一下总结. 1 明确题意 题目中的子数组要求是连续的,也就是数组中的某个连续部分. 如果数组中都是正整数,直接相加就行.因此,主要是要考虑负数的情况. 2 直接求所有的子数组和 最简单且容易理解的解法是求出所有的子数组和,然后保存最大的和. int MaxSum(int *A, int n) { int maximum = -INF; int sum = 0; int i =

编程之美 2.14求数组的子数组之和的最大值

对于一个有N个元素的数组,a[0]~a[n-1],求子数组最大值. 如:数组A[] = [−2, 1, −3, 4, −1, 2, 1, −5, 4],则连续的子序列[4,−1,2,1]有最大的和6. 方法一:暴力 循环遍历,输出所有,判断最大的和 1 #include"iostream" 2 #define MAX 1001 3 using namespace std; 4 5 int main(){ 6 int n, a[MAX], sum , maxsum ; 7 8 cin &

编程之美读书笔记2.14 - 子数组之和的最大值

http://blog.csdn.net/pipisorry/article/details/39083281 问题: 1. 一个由N个整数元素的一维数组,求其所有子数组中元素和的最大值. 2. 如果数组首尾相邻,也就是允许子数组A[i],...,A[n-1],A[0],...,A[j]存在,求其所有子数组总元素和的最大值. 解法1: /* O(n^2) 遍历算法 */ static int maxSubarraySum1(int *a,int a_len){ int max_sum = INT

编程之美2.14 求数组的子数组之和的最大值

问题描述: 一个有N个整数元素的一维数组(A[0], A[1], A[2],...,A[n-1]),这个数组当然有很多子数组,那么子数组之和的最大值是什么呢? 解法: 1. 暴力解法-------O(N^3) 2. 改进版暴力解法-------O(N^2) *3. 分治算法-------O(NlogN)(暂时未去实现) 4. 数组间关系法-------O(N) 具体思路和代码: 1.暴力解法 思路:Sum[i,...,j]为数组第i个元素到第j个元素的和,遍历所有可能的Sum[i,...,j].

第2章 数字之魅——子数组之和的最大值(二维)

子数组之和的最大值(二维) 问题描述 我们在前面分析了一维数组之和的最大值问题,那么如果是二维数组又该如何分析呢? 分析与解法 最直接的方法,当然就是枚举每一个矩形区域,然后再求这个矩形区域中元素的和. [解法一] 完整代码如下: 1 package chapter2shuzizhimei.maxsumsubarraytwodimensional; 2 /** 3 * 求数组的子数组之和的最大值(二维) 4 * [解法一] 5 * @author DELL 6 * 7 */ 8 public c