LeetCode HOT100系列题解之最大正方形(6/100)

题目:最大正方形. - 力扣(LeetCode)

题解:

第一种方法:前缀和+二分答案(暴力优化) 我感觉比官方给的暴力好一点

时间复杂度:

  • 暴力优化1: 通过前缀和减少判断1出现得次数**(这个题比较特别,只有0,1)**
  • **暴力优化2:**答案单调,二分答案

在check函数中,我去找了当答案为x时,即找到所有x * x得正方形来进行判断,如果它得值为x * x,那么说明答案成立。

代码1

cpp 复制代码
class Solution {
public:
    bool check(int x, int n, int m, const vector<vector<int>>& sum)
    {
        if(x == 0) return true;

        int ans = x * x;
        for(int i = x; i <= n; i ++)
        {
            for(int j = x; j <= m; j ++)
            {
                int x1 = i - x + 1;
                int y1 = j - x + 1;
                int x2 = i;
                int y2 = j;

                if(sum[x2][y2] - sum[x1-1][y2] - sum[x2][y1-1] + sum[x1-1][y1-1] == ans)
                    return true; 
            }
        }
        return false;
    }
    int maximalSquare(vector<vector<char>>& matrix) {
        int n = matrix.size();
        int m = matrix[0].size();

        vector<vector<int>>sum;
        sum.resize(n + 1, vector<int>(m + 1, 0));

        for(int i = 1; i <= n; i ++)
            for(int j = 1; j <= m; j ++)
            {
                 sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + (matrix[i - 1][j - 1] == '1');
                 //cout << sum[i][j] << endl;
            }
               
  
        int l = 0, r = min(n, m);

        while(l <= r)
        {
            int mid = l + (r + 1) >> 1;
            if(check(mid, n, m, sum)) l = mid + 1;
            else r = mid - 1; 
        }
        
        return (l - 1) * (l - 1);
    }
};

第二种方法:DP(动态规划)

题解来源:该题官网题解。

时间复杂度:

这里仅解释一下为什么转移方程是

通俗易懂得理解方法是,因为本题需要得是正方形,因此仅需要保证周围点为1且加上自己构成正方形即可。如果左、上、左上有一个点为0,那么将无法转移。至于为什么不会被判断成长方形呢?可以看到

代码2:

cpp 复制代码
class Solution {
public:
    int maximalSquare(vector<vector<char>>& matrix) {
        int n = matrix.size();
        int m = matrix[0].size();
        
        int ans = 0;
        
        vector<vector<int>>dp(n + 1, vector<int>(m + 1, 0));
        for(int i = 1; i <= n; i ++)
        {
            for(int j = 1; j <= m; j ++)
            {
                if(matrix[i-1][j-1] == '0') dp[i][j] = 0;
                else
                {
                    dp[i][j] = min(dp[i-1][j], min(dp[i][j-1], dp[i-1][j-1])) + 1;//保证周围点为正方形
                }
                ans = max(ans, dp[i][j]);
                
            }
        }
        return ans * ans;
    }
};

思考:

思考二:如果是求长方形,又该如何去做?

这个题就会变得非常有趣。动态规划应该依旧有求解得办法,但是原方程必定失效。而这个题是LeetCode 85 85.最大矩形. - 力扣(LeetCode)得题,使用的是单调栈来求解,我将在后续对这个题单独学习。

相关推荐
梵刹古音1 小时前
【C语言】 字符数组相关库函数
c语言·开发语言·算法
wfeqhfxz25887828 小时前
YOLO13-C3k2-GhostDynamicConv烟雾检测算法实现与优化
人工智能·算法·计算机视觉
芝士爱知识a8 小时前
2026年AI面试软件推荐
人工智能·面试·职场和发展·大模型·ai教育·考公·智蛙面试
Aaron15889 小时前
基于RFSOC的数字射频存储技术应用分析
c语言·人工智能·驱动开发·算法·fpga开发·硬件工程·信号处理
石去皿10 小时前
大模型面试通关指南:28道高频考题深度解析与实战要点
人工智能·python·面试·职场和发展
程序员辣条10 小时前
AI产品经理:2024年职场发展的新机遇
人工智能·学习·职场和发展·产品经理·大模型学习·大模型入门·大模型教程
AI大模型测试10 小时前
大龄程序员想转行到AI大模型,好转吗?
人工智能·深度学习·机器学习·ai·语言模型·职场和发展·大模型
美团程序员10 小时前
80道经典常见测试面试题
软件测试·面试·职场和发展·软件测试面试
sunguang201810 小时前
“懂不懂管理,一看便知”:做管理就是3件事,抓大、放小、管细做管理,其实就是要做好三件事:抓大、放小、管细。
经验分享·职场和发展
ProcessOn官方账号10 小时前
程序员如何与同龄人拉开差距?这5张让你快速提升认知,打开格局!
深度学习·职场和发展·学习方法