蓝桥杯——子矩阵的最大累加和

题目描述:给定一个矩阵matrix,其中有正、有负、有0,返回子矩阵的最大累加和。
例如,matrix为:
{{-1,-1,-1},
{-1 , 2 , 2},
{-1,-1,-1}}
其中最大累加和的子矩阵为:
2,2
所以返回4

解题思路

这道题的关键在于必须是子矩阵,而子矩阵的情况太多了,如果一一列举的话想必是不能达到要求的。所以这道题需要对原二维数组(矩阵)进行一些预处理,也就是降维度或压缩,方法就是对矩阵按列求和,然后按照一位数组的思想去求这个最大累加和。我之前有写过一篇一位数组解决类似问题的文章,可以去看一下。一位数组求子数组的最大累加和

有了这样的处理真的就很方便地可以解决啦

//子矩阵的最大累加和,注意:也要是连续的子矩阵
#include<iostream>
#include<cstring>
#define N 3

using namespace std;

int findMax(int arr[]);
int solve(int matrix[][N],int M){
	int helper[N] = {0};  //辅助数组用于压缩 
	int beginRow,j,k;
	int tmpMax,max=helper[0];
	while(beginRow < M){
		for(j = beginRow; j<M; j++){
			for(k = 0; k<N; k++){   //按列求和 
				helper[k] += matrix[j][k];
			}
			//求完了就去找压缩后数列的最大值
			tmpMax = findMax(helper); 
			if(tmpMax > max){
				max = tmpMax;
			}
	}
	memset(helper,0,N*sizeof(int));  //helper清零
	beginRow++;
	}
		
		return max;
}
int findMax(int arr[]){
	int sentry=0 , cursor=0 ;   //定义哨兵和游标 
	int maxSum = arr[0];  //最大的和 
	int tmpSum = 0;
	int end;
	
		while(cursor < N ){
			tmpSum += arr[cursor];
			cursor ++;
			if(tmpSum < 0){   //如果是负的,就说明是负贡献,应该调整哨兵 
				sentry = cursor;
				tmpSum = 0;  //归零 
				continue;
			}
			if(tmpSum > maxSum){
				maxSum = tmpSum;
				end = cursor-1;
			} 
		}
	return maxSum;
}  
int main(){
	int matrix[][N] = {
	{-1,1,1},
	{-1,2,-2},
	{-1,1,1}
	};
	int res = solve(matrix,3);
	cout<<"result: "<<res;
}
运行结果示例

在这里插入图片描述

时间复杂度分析

这道题的时间复杂度是O(M✖N),其中由于按列求和时beginRow要走M行,而求最大子数组累加和的时候是线性的O(N)(可以参考上一篇文章的分析)。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值