关闭

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

标签: 二维数组子数组之和最大值
442人阅读 评论(0) 收藏 举报
分类:

我们在前面分析了一维数组的子数组之和最大值的问题,那么如果是二维数组又该如何分析呢?

最直接的方法,当然就是枚举每一个矩形区域,然后再求这个矩形区域中元素的和。

解法一:枚举

  采用这种方法的时间复杂度为O(N2*M2*sum的时间复杂度)。

  对于部分和sum,可以作一个预处理,设p[i][j]表示从arr[0][0]加到arr[i][j]的和;

  则从arr[i1][j1]加到arr[i2][j2]的和为:

  sum(arr, i1, i2, j1, j2) = p[i2][j2] + p[i1-1][j1-1] - p[i1-1][j2] - p[i2-1][j1]

  这个预处理的时间复杂度为O(NM),算法时间复杂度为O(N2*M2)。

方法二:动态规划

  假设已经确定了矩形区域的上下边界,比如知道矩形区域的上下边界分别是第a行和第c行,现在要确定左右边界。

  其实这个问题就是一维的,可以把每一列中第a行和第c行之间的元素看成一个整体。即求数组(BC[1], ..., BC[M])中和最大的一段,其中BC[i]=B[a][i] + ... + B[c][i]。

  这样,我们枚举矩形的上下边界,然后再用一维情况下的方法确定左右边界,就可以得到二维问题的解。新的方法的时间复杂度为O(N*M*min(N, M))。

public class Array_2 
{
	public static void main(String[] args)
	{
		int[][] h={{1,2,3},{4,-5,6},{7,8,9}};
		System.out.println(Maxsum_2(h));
		
	}
	public static int Maxsum_2(int[][] arr)
	{
		int maxumum=Integer.MIN_VALUE;
		for(int i=0;i<arr.length;i++)
		{
			for(int j=i;j<arr.length;j++)
			{
				//System.out.print("i="+i+"j="+j+" ");
				int sum=0;
				int[] n = new int[arr[0].length];
				for(int w=0;w<arr[0].length;w++)
				{
					sum=0;
					for(int k=i;k<=j;k++)
					{
						sum = sum+arr[k][w];
					}
					n[w]=sum;
					//System.out.print(w+" "+n[w]+" ");
				}
				if(Maxsum_ultimate(n)>maxumum)
					maxumum =Maxsum_ultimate(n);
			}
		}
		return maxumum;
	}
	public static int Maxsum_ultimate(int[] arr)//一维数组子数组最大计算公式,O(N).
	{
		int maxSum = Integer.MIN_VALUE;
		int sum = 0;
		for(int i = 0; i < arr.length; ++i)
		{
			if(sum < 0)
			{
				sum = arr[i];
			}else
			{
				sum += arr[i];
			}
			if(sum > maxSum)
			{
				maxSum = sum;
			}
		}
	return maxSum;
}
}
结果如下:

35


0
0
查看评论

最大子矩阵:二维数组的最大连续子数组和

上篇讲了一维的连续子数组和的最大值(编程之美错误分析),下面来分析二维数组的最大子数组和,亦称最大子矩阵, 穷举法: //求二维数组的连续子数组之和的最大值   int MaxSum(int (*array)[N])   {    int i,j;    int MaxSum=-INFINITY;/...
  • hxz_qlh
  • hxz_qlh
  • 2013-11-11 16:02
  • 1804

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

【题目】 一个有N个整数元素的一维数组(A[0],A[1],A[2],...A[n-1]),这个数组中当然有很多子数组,那么子数组之和的最大值是多少? 该子数组是连续的。 我们先来明确一下题意: (1)子数组意味着是连续的。 (2)题目只需要求和,并不需要返回子数组的具体位置。 (3)数...
  • SunnyYoona
  • SunnyYoona
  • 2014-05-19 23:34
  • 1850

求数组的连续子数组之和的最大值

一个有N个整数元素的一维数组{A[0],A[1],....,A[N-1],A[N]},这个数组有很多子数组,那么子数组之和的最大值是什么?    先给出一个时间复杂度为O(N^2)的求解程序实现,思想很简单,就是遍历数组中所有的子数组,代码如下: /** * 计算数组的最...
  • WitsMakeMen
  • WitsMakeMen
  • 2013-04-24 22:47
  • 4973

【编程之美】读书笔记:求数组的子数组之和的最大值

问题:一个有N个整数元素的一维数组(A[0],A[1],A[2],...A[n-1]),这个数组中子数组之和的最大值是多少? 该子数组是连续的。例如 数组:[1,-2,3,5,-3,2]返回8; 数组:[0,-2,3,5,-1,2]返回9       ...
  • xiaoding133
  • xiaoding133
  • 2012-10-03 16:33
  • 3247

求数组中的子数组之和的最大值

《编程之美》第2.14节:求数组中的子数组之和的最大值 题目:有一个有N个元素组成的一维数组,这个数组中当然有很多子数组,那么子数组之和的最大值是多少? 解法:从头到尾遍历整个数组,不断加和,如果临时和temp 代码如下: #include #include using namespace ...
  • u010585135
  • u010585135
  • 2015-01-05 21:00
  • 1415

LintCode 138. 子数组之和

思路: 方法一:最直观的想法是, 对每一个区间, 计算其中数值的和.若为0则返回此区间, 此方法复杂度为O(n^3). 方法二:方法一中进行了大量的重复计算, 故可以存储区间的计算值, 则此区间的父区间计算时不用再对此区间进行求值而可以直接对值进行使用.此方法复杂度为O(n^2) 方法三:...
  • github_34248245
  • github_34248245
  • 2016-03-16 12:00
  • 629

LintCode:子数组之和

LintCode:子数组之和方法一:O(n^2)复杂度:Pythonclass Solution: """ @param nums: A list of integers @return: A list of integers includes ...
  • u012225151
  • u012225151
  • 2016-05-12 19:35
  • 378

连续子数组的最大和问题(一维和二维)To the Max (POJ 1050)

一维数组的连续子数组的最大和 题目:输入一个整型数组,数组里有正数也有负数。数组中一个或连续的多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为O(n)。 这是一个典型的DP问题,递推公式是DP(i) = max{DP(i-1) + A(i),A(i)} 解释:DP...
  • huanyingtianhe
  • huanyingtianhe
  • 2015-01-25 16:35
  • 1175

二维数组的子数组之和的最大值

对于一维的数组,要求其子数组之和的最大值很简单,动态规划轻松解决,复杂度O(N) 代码如下: #include using namespace std; int MaxSum(int a[],int n) { int start = a[0]; int max = a[0]; for(i...
  • ButterflyDRM
  • ButterflyDRM
  • 2013-10-08 21:16
  • 325

lintcode-子数组之和-138

给定一个整数数组,找到和为零的子数组。你的代码应该返回满足要求的子数组的起始位置和结束位置 样例 给出[-3, 1, 2, -3, 4],返回[0, 2] 或者 [1, 3]. 第一种思路:利用两个for循环,每次取出一个元素依次与后面的元素相加,时间复杂...
  • ljlstart
  • ljlstart
  • 2015-09-12 14:02
  • 1031
    个人资料
    • 访问:101557次
    • 积分:1938
    • 等级:
    • 排名:千里之外
    • 原创:93篇
    • 转载:43篇
    • 译文:0篇
    • 评论:8条
    最新评论