【leetcode】221. Maximal Square

本文介绍了两种解决最大正方形问题的方法,一种时间复杂度为O(nmlogm),空间复杂度为O(m),另一种时间复杂度为O(nm),空间复杂度为O(nm)。方法一通过一维化和寻找最左最右下标实现,方法二使用动态规划构建求解矩阵。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

解法一: 时间复杂度 O(nm logm),空间O(m)

将二维化为一维。累计1的高度,在每次累计时,求最值。

转化为一维后。用两个数组,分别存放当下标为j时,大于等于当前高度的最左的下标值,以及

大于等于当前高度的最右的下标值。

/**
 * @author          johnsondu
 * @problem         Maximal Square
 * @time            O(nm logm)
 * @space           O(n)
 * @url             https://leetcode.com/problems/maximal-square/
 * @strategy        dynamic programs.
 * @status          Accepted,  runtime beats 18.90% of cpp submissions. 16ms
 * @time            15:25, Nov 4th 2015
 */

class Solution {
public:
    int maximalSquare(vector<vector<char>>& matrix) {
        int row = matrix.size();
        if(row < 1) return 0;
        int col = matrix[0].size();
        int ans = 0;

        vector<int> dp(col+2, 0);
        vector<int> lidx(col+1, 0);
        vector<int> ridx(col+1, 0);
        dp[0] = -1;
        dp[col + 1] = col+1;

        for(int i = 0; i < row; i ++) {
            // 将二维,转化为一维,每次累计高度。转换成
            // hdu 1506的做法。
            for(int j = 0; j < col; j ++) {
                if(matrix[i][j] == '1') dp[j+1] = dp[j+1] + 1;
                else dp[j+1] = 0;
            }

            for(int j = 1; j <= col; j ++) lidx[j] = ridx[j] = j;

            // 找到当前每个下标的至少和当前高度持平的最左下标值
            for(int j = 1; j <= col; j ++) {
                // 如果当前高度小于等于t时的当前高度,那么
                //  当前高度一定也小于等于下标t的最左的大于等于下标t的高度。
                int t = j-1;
                while(dp[j] <= dp[t] && t > 0) {
                    t = lidx[t];
                }
                lidx[j] = t;
            }
            // 找到当前每个下标的至少和当前高度持平的最右下标值
            for(int j = col; j > 0; j --) {
                // 同理
                int t = j+1;
                while(dp[j] <= dp[t] && t <= col) {
                    t = ridx[t];
                }
                ridx[j] = t;
            }
            // 求最大值
            for(int j = 1; j <= col; j ++) {
                ans = max(ans, min(ridx[j] - lidx[j] - 1, dp[j]));
            }
        }
        return ans * ans;
    }
};


解法二: 时间复杂度O(nm), 空间复杂度O(nm)

解法如下:

1) Construct a sum matrix S[R][C] for the given M[R][C].
     a) Copy first row and first columns as it is from M[][] to S[][]
     b) For other entries, use following expressions to construct S[][]
         If M[i][j] is 1 then
            S[i][j] = min(S[i][j-1], S[i-1][j], S[i-1][j-1]) + 1
         Else /*If M[i][j] is 0*/
            S[i][j] = 0
2) Find the maximum entry in S[R][C]
3) Using the value and coordinates of maximum entry in S[i], print 
   sub-matrix of M[][]


/**
 * @author          johnsondu
 * @problem         Maximal Square
 * @time            O(nm)
 * @space           O(nm)
 * @url             https://leetcode.com/problems/maximal-square/
 * @strategy        dynamic programs.
 * @status          Accepted,  runtime beats 30.20% of cpp submissions. 12ms
 * @time            15:55, Nov 4th 2015
 */

class Solution {
public:
    int maximalSquare(vector<vector<char>>& matrix) {
        int row = matrix.size();
        if(row < 1) return 0;
        int col = matrix[0].size();
        int ans = 0;

        vector<vector<int>> dp(row, vector<int>(col, 0));
        for(int i = 0; i < row; i ++)
            if(matrix[i][0] == '1') dp[i][0] = 1;
        for(int i = 0; i < col; i ++)
            if(matrix[0][i] == '1') dp[0][i] = 1;

        for(int i = 1; i < row; i ++)
        for(int j = 1; j < col; j ++) {
            if(matrix[i][j] == '1')
                dp[i][j] = min(min(dp[i][j-1], dp[i-1][j]), dp[i-1][j-1]) + 1;
            else dp[i][j] = 0;
        }

        for(int i = 0; i < row; i ++)
            for(int j = 0; j < col; j ++)
                ans = max(ans, dp[i][j]);
        return ans * ans;
    }
};


### 如何在 VSCode 中安装和配置 LeetCode 插件以及 Node.js 运行环境 #### 安装 LeetCode 插件 在 VSCode 的扩展市场中搜索 `leetcode`,找到官方提供的插件并点击 **Install** 按钮进行安装[^1]。如果已经安装过该插件,则无需重复操作。 #### 下载与安装 Node.js 由于 LeetCode 插件依赖于 Node.js 环境,因此需要下载并安装 Node.js。访问官方网站 https://nodejs.org/en/ 并选择适合当前系统的版本(推荐使用 LTS 版本)。按照向导完成安装流程后,需确认 Node.js 是否成功安装到系统环境中[^2]。 可以通过命令行运行以下代码来验证: ```bash node -v npm -v ``` 上述命令应返回对应的 Node.js 和 npm 的版本号。如果没有正常返回版本信息,则可能未正确配置环境变量。 #### 解决环境路径问题 即使完成了 Node.js 的安装,仍可能出现类似 “LeetCode extension needs Node.js installed in environment path” 或者 “command ‘leetcode.toggleLeetCodeCn’ not found” 的错误提示[^3]。这通常是因为 VSCode 未能识别全局的 Node.js 路径或者本地安装的 nvm 默认版本未被正确加载[^4]。 解决方法如下: 1. 手动指定 Node.js 可执行文件的位置 在 VSCode 设置界面中输入关键词 `leetcode`,定位至选项 **Node Path**,将其值设为实际的 Node.js 安装目录下的 `node.exe` 文件位置。例如:`C:\Program Files\nodejs\node.exe`。 2. 使用 NVM 用户管理工具调整默认版本 如果通过 nvm 工具切换了不同的 Node.js 版本,请确保设置了默认使用的版本号。可通过以下指令实现: ```bash nvm alias default <version> ``` 重新启动 VSCode 后测试功能键是否恢复正常工作状态。 --- #### 配置常用刷题语言 最后一步是在 VSCode 设置面板中的 LeetCode 插件部分定义个人习惯采用的主要编程语言作为默认提交方式之一。这样可以减少频繁修改编码风格的时间成本。 --- ### 总结 综上所述,要在 VSCode 上顺利启用 LeetCode 插件及其关联服务,除了基本插件本身外还需额外准备支持性的后台框架——即 Node.js 应用程序引擎;同时针对特定场景下产生的兼容性障碍采取针对性措施加以修正即可达成目标[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值