连续子数组(二维)的最大和

题目连接如下:

http://www.acmerblog.com/max-sum-rectangle-in-a-matrix-5955.html

一维数组的连续子数组的最大和

题目:输入一个整型数组,数组里有正数也有负数。数组中一个或连续的多个整数组成一个子数组。求所有子数组的和的最大值。要求时间负责度为O(n)。

假如输入数组为{1,-2,3,10,-4,7,2,-5},我们尝试从头到尾累加其中的正数,初始化和为0,第一步加上1,此时和为1,第二步加上-2,此时和为-1,第三步加上3,此时我们发现-1+3=2,最大和2反而比3一个单独的整数小,这是因为3加上了一个负数,发现这个规律以后我们就重新作出累加条件:如果当前和为负数,那么就放弃前面的累加和,从数组中的下一个数再开始计数。

剑指offer和编程之美都有此题。参考这里:剑指offer(14)-最大子向量和 九度1372。算法可以优化为下面的几行代码:

二维数组的连续子数组的最大和

二维数组的连续子数组即为一个矩阵,如下图所示

设矩阵的坐上顶点为A(i,j), 右下顶点为 B(endi, endj). 在图中即为 A(1,1), B(3,3)。我们可以用Rect(A,B)即 (1,1,3,3,)来表示矩形区域。

代码:

#include<cstdio>
#include<iostream>
using namespace std;

int a[100][100];
int n,m;
int p[100][100];

int main()
{
    freopen("in.txt","r",stdin);
    int i,j;
    int max , imax , jmax , istart , jend;
    while( ~scanf("%d%d",&n,&m) )
    {
        memset(a , 0 , sizeof(a) );
        for( i = 0 ; i < n ; i++ )
        {
            for( j = 0 ; j < m ; j++ )
            {
                scanf("%d",&a[i][j]);
                p[i][j] = a[i][j];
                if( j -1 >= 0 )
                    p[i][j] += p[i][j-1];
                if( i -1 >= 0 )
                    p[i][j] += p[i-1][j];
                if( i-1 >=0 && j-1 >= 0 )
                    p[i][j] -= p[i-1][j-1];
            }
        }
        for( i = 0 ; i < n ; i++ )
        {
            for( j = 0 ; j < m ; j++ )
                printf("%3d  ", p[i][j] );
            printf("\n");
        }
        max = a[0][0];
        int temp , tempstart , tempend;
        int z;
        for( i = 0 ; i < n; i++ )
        {
            for( j = i ; j < n ; j++ )
            {
                temp = p[j][0];
                if( i - 1 >= 0 )
                    temp -= p[i-1][0];
                tempstart = tempend = 0;
                for( z = 1; z < m ; z++)
                {
                    int zz = p[j][z];
                    if( z -1 >= 0 )
                        zz -= p[j][z-1];
                    if( i - 1 >= 0 )
                        zz -= p[i-1][z];
                    if( i-1>= 0 && z-1 >= 0 )
                        zz += p[i-1][z-1];
                    if( (temp + zz) > zz )
                    {
                        temp = temp + zz;
                        tempend = z;
                    }
                    else
                    {
                        temp = zz;
                        tempstart = tempend = z;
                    }
                    if( temp > max )
                    {
                        max = temp;
                        imax = i; jmax = j;
                        istart = tempstart; jend = tempend;
                    }
                }
            }
        }
        printf("(%d,%d) - (%d,%d) sum is %d \n" , imax , istart , jmax , jend , max );
    }
    return 0;
}
时间: 2025-01-31 19:48:05

连续子数组(二维)的最大和的相关文章

剑指offer(二十三,二十四,二十五)最小的k个数,连续子数组的最大和,链表中环的入口节点

23:最小的k个数 题目描述 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 简单题.... function GetLeastNumbers_Solution(input, k) { if(k>input.length) return []; let ans = []; input = input.sort(); //console.log(input.join("").slice(0,4).split

求连续子数组的最大和

一.题目: 这是一道考的烂的不能再烂的题目,但是依然有很多公司乐于将这样的题目作为笔试或面试题,足见其经典. 问题是这样的:一个整数数组中的元素有正有负,在该数组中找出一个连续子数组,要求该连续子数组中各元素的和最大,这个连续子数组便被称作最大连续子数组.比如数组{2,4,-7,5,2,-1,2,-4,3}的最大连续子数组为{5,2,-1,2},最大连续子数组的和为5+2-1+2=8. 二.解法: 解法一:暴力求解法 /* (1) 常规方法,时间复杂度O(n*n) (2) 先从第一个元素开始向后

【剑指Offer学习】【面试题31:连续子数组的最大和】

题目:输入一个整型数组,数组里有正数也有负数.数组中一个或连续的多个整数组成一个子数组.求所有子数组的和的最大值.要求时间复杂度为O(n). 例子说明: 例如输入的数组为{1, -2, 3, 10, -4, 7, 2, -5},和最大的子数组为{3, 10, -4, 7, 2}.因此输出为该子数组的和18 . 解题思路: 解法一:举例分析数组的规律. 我们试着从头到尾逐个累加示例数组中的每个数字.初始化和为0.第一步加上第一个数字1, 此时和为1.接下来第二步加上数字-2,和就变成了-1.第三步

剑指Offer面试题:28.连续子数组的最大和

一.题目:连续子数组的最大和 题目:输入一个整型数组,数组里有正数也有负数.数组中一个或连续的多个整数组成一个子数组.求所有子数组的和的最大值.要求时间复杂度为O(n).例如输入的数组为{1,-2,3,10,-4,7,2,-5},和最大的子数组为{3,10,-4,7,2},因此输出为该子数组的和18. 这个题目在我去年参加校园招聘时,某公司的二面采用了机试,而题目刚好就是这道题.一般看到这道题目就会想到枚举出数组的所有子数组并求出它们的和.一个长度为n的数组,总共有n(n+1)/2个子数组.计算

剑指offer 连续子数组的最大和

在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决.但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止).你会不会被他忽悠住? 一. 动态规划 设sum[i]为以第i个元素结尾且和最大的连续子数组.假设对于元素i,所有以它前面的元素结尾的子数组的长度都已经求得,那么以第i个元素结尾且和最大的连续子数组实际上,要么是以第i-1个元素结

剑指offer面试题31连续子数组的最大和

一.题目描述 HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学.今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决.但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止).你会不会被他忽悠住? 二.解题思路 求连续子数组的最大和,首先想的到最笨的方法就是暴力解决,两个for循环,遍历数组找到和最大的子

连续子数组的最大和问题

参考自:求连续子数组的最大和 求子数组的最大和题目描述:输入一个整形数组,数组里有正数也有负数.数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和.求所有子数组的和的最大值.要求时间复杂度为O(n). 例如输入的数组为1, -2, 3, 10, -4, 7, 2, -5,和最大的子数组为3, 10, -4, 7, 2,因此输出为该子数组的和18. 思路 一.暴力求法 计算每一个子数组的和,然后求最大值,复杂度O(n3).不推荐,代码就不写了. 二. 动态规划 设sum[i]为以第i个

python实现连续子数组的最大和

题目描述 HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学.今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决.但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止).给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住?(子向量的长度至少是1) 方法一:穷举法 我们很自然地能想到穷举的办法,穷

剑指Offer3_连续子数组的最大和

一.题目描述 HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学.今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决.但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止).给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住?(子向量的长度至少是1) 二.解题思路 开始看到这道题是有点懵的,甚至