面试题 17.24. 最大子矩阵 力扣 ,难 类最大连续子串和

给定一个正整数、负整数和 0 组成的 N × M 矩阵,编写代码找出元素总和最大的子矩阵。

返回一个数组 [r1, c1, r2, c2],其中 r1, c1 分别代表子矩阵左上角的行号和列号,r2, c2 分别代表右下角的行号和列号。若有多个满足条件的子矩阵,返回任意一个均可。

注意:本题相对书上原题稍作改动

输入:
[
   [-1,0],
   [0,-1]
]
输出:[0,1,0,1]

题源:https://leetcode-cn.com/problems/max-submatrix-lcci/

题解:https://leetcode-cn.com/problems/max-submatrix-lcci/solution/zhe-yao-cong-zui-da-zi-xu-he-shuo-qi-you-jian-dao-/

参考:

53. 最大子序和
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

这是一个简单的dp问题
1、状态定义:dp[i]为以nums[i]结尾的最大子序和
2、状态转移方程:对于nums[i]有两种情况:一种是和前一个位置的子序列连着dp[i]=dp[i-1]+nums[i]
第二种是以自己独立门户,从自己开始dp[i]=nums[i]
取其中最大值,可得状态转移方程为dp[i]=max( dp[i-1] + nums[i] , nums[i] )
3、basecase:dp[0]=nums[0]很好理解

学习点:

1、vector<int> 可以用 ={ 1,2,3} 直接赋值

class Solution {
public:
    vector<int> getMaxMatrix(vector<vector<int>>& matrix) {
        int n=matrix.size();
        int m=matrix[0].size();
       
        vector<vector<int>> f(n+1,vector<int>(m+1,0));
       
        for(int j=0;j<m;j++)  //每列前缀和
            for(int i=0;i<n;i++)
                if (i>0)  f[i][j]=f[i-1][j]+matrix[i][j];
                  else f[i][j]=matrix[i][j];
       

        int res=-0x7fffffff;
        vector<int> ress;
        int b[205];

        for (int i=0;i<n;i++)    //枚举矩阵的上下边界
            for(int j=i;j<n;j++)
            {
                int iy=0,sum=0;
                for(int k=0;k<m;k++)  //枚举结束的列坐标
                {
                    if (i>0) b[k]=f[j][k]-f[i-1][k];
                     else b[k]=f[j][k];
                    if(sum+b[k]>=b[k]) sum=sum+b[k];  //sum记录了,以k列结尾的,最大子序列和,原来使用dp[i]记录,由于本题不需要记录
                     else
                    {
                        sum=b[k];
                        iy=k;
                    }     

                    if (sum>=res)
                    {
                        res=sum;
                        ress={i,iy,j,k};
                    }
                }          
            }
        
        return ress;
    }
};

 

posted on 2021-06-03 17:04  Yxter  阅读(86)  评论(0编辑  收藏  举报

导航