221. Maximal Square
Medium

Given a 2D binary matrix filled with 0's and 1's, find the largest square containing only 1's and return its area.

Example:

Input: 

1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0 Output: 4
 
 

To appy DP, we define the state as the maximal size (square = size * size) of the square that can be formed till point (i, j), denoted as dp[i][j].

For the topmost row (i = 0) and the leftmost column (j = 0), we have dp[i][j] = matrix[i][j] - '0', meaning that it can at most form a square of size 1 when the matrix has a '1'in that cell.

When i > 0 and j > 0, if matrix[i][j] = '0', then dp[i][j] = 0 since no square will be able to contain the '0' at that cell. If matrix[i][j] = '1', we will have dp[i][j] = min(dp[i-1][j-1], dp[i-1][j], dp[i][j-1]) + 1, which means that the square will be limited by its left, upper and upper-left neighbors.

class Solution {
public:
int maximalSquare(vector<vector<char>>& matrix) {
if (matrix.empty()) {
return ;
}
int m = matrix.size(), n = matrix[].size(), sz = ;
vector<vector<int>> dp(m, vector<int>(n, ));
for (int i = ; i < m; i++) {
for (int j = ; j < n; j++) {
if (!i || !j || matrix[i][j] == '') {
dp[i][j] = matrix[i][j] - '';
} else {
dp[i][j] = min(dp[i - ][j - ], min(dp[i - ][j], dp[i][j - ])) + ;
}
sz = max(dp[i][j], sz);
}
}
return sz * sz;
}
};

In the above code, it uses O(mn) space. Actually each time when we update dp[i][j], we only need dp[i-1][j-1]dp[i-1][j] (the previous row) and dp[i][j-1] (the current row). So we may just keep two rows.

class Solution {
public:
int maximalSquare(vector<vector<char>>& matrix) {
if (matrix.empty()) {
return ;
}
int m = matrix.size(), n = matrix[].size(), sz = ;
vector<int> pre(n, ), cur(n, );
for (int i = ; i < m; i++) {
for (int j = ; j < n; j++) {
if (!i || !j || matrix[i][j] == '') {
cur[j] = matrix[i][j] - '';
} else {
cur[j] = min(pre[j - ], min(pre[j], cur[j - ])) + ;
}
sz = max(cur[j], sz);
}
fill(pre.begin(), pre.end(), );
swap(pre, cur);
}
return sz * sz;
}
};

Furthermore, we may only use just one vector (thanks to @stellari for sharing the idea).

class Solution {
public:
int maximalSquare(vector<vector<char>>& matrix) {
if (matrix.empty()) {
return ;
}
int m = matrix.size(), n = matrix[].size(), sz = , pre;
vector<int> cur(n, );
for (int i = ; i < m; i++) {
for (int j = ; j < n; j++) {
int temp = cur[j];
if (!i || !j || matrix[i][j] == '') {
cur[j] = matrix[i][j] - '';
} else {
cur[j] = min(pre, min(cur[j], cur[j - ])) + ;
}
sz = max(cur[j], sz);
pre = temp;
}
}
return sz * sz;
}
};

LeetCode | DP专题详解的更多相关文章

  1. 状压DP入门详解+题目推荐

    在动态规划的题型中,一般叫什么DP就是怎么DP,状压DP也不例外 所谓状态压缩,一般是通过用01串表示状态,充分利用二进制数的特性,简化计算难度.举个例子,在棋盘上摆放棋子的题目中,我们可以用1表示当 ...

  2. Leetcode之动态规划(DP)专题-详解983. 最低票价(Minimum Cost For Tickets)

    Leetcode之动态规划(DP)专题-983. 最低票价(Minimum Cost For Tickets) 在一个火车旅行很受欢迎的国度,你提前一年计划了一些火车旅行.在接下来的一年里,你要旅行的 ...

  3. LeetCode专题——详解搜索算法中的搜索策略和剪枝

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是LeetCode专题第20篇文章,今天讨论的是数字组合问题. 描述 给定一个int类型的候选集,和一个int类型的target,要求返 ...

  4. Leetcode之广度优先搜索(BFS)专题-详解429. N叉树的层序遍历(N-ary Tree Level Order Traversal)

    Leetcode之广度优先搜索(BFS)专题-429. N叉树的层序遍历(N-ary Tree Level Order Traversal) 给定一个 N 叉树,返回其节点值的层序遍历. (即从左到右 ...

  5. LeetCode dp专题

    1. 动态规划的适用场景 动态规划常常适用于有重叠子问题和最优子结构性质的问题,动态规划方法所耗时间往往远少于朴素解法. 2. 动态规划的基本思想 动态规划背后的基本思想非常简单.大致上,若要解一个给 ...

  6. 分布式专题——详解Google levelDB底层原理

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是分布式专题的第10篇文章,我们继续来聊聊LSMT这个数据结构. LSMT是一个在分布式系统当中应用非常广泛,并且原理直观简单的数据结构 ...

  7. 【动态规划】树形DP完全详解!

    蒟蒻大佬时隔三个月更新了!!拍手拍手 而且是更新了几篇关于DP的文章(RioTian狂喜) 现在赶紧学习和复习一下树形DP.... 树形DP基础:Here,CF上部分树形DP练习题:Here \[QA ...

  8. poj1417 true liars(并查集 + DP)详解

    这个题做了两天了.首先用并查集分类是明白的, 不过判断是否情况唯一刚开始用的是搜索.总是超时. 后来看别人的结题报告, 才恍然大悟判断唯一得用DP. 题目大意: 一共有p1+p2个人,分成两组,一组p ...

  9. LeetCode Permutations问题详解

    题目一 permutations 题目描述 Given a collection of numbers, return all possible permutations. For example,[ ...

随机推荐

  1. Amazon Redshift and the Case for Simpler Data Warehouses

    Redshift是Amazon一个商业产品上的进化 但并不是技术的进化,他使用的无非都是传统数仓领域的技术 如果说创新,就是大量使用Amazon本身的云服务的云原生架构,大大提升的产品的迭代速度,可维 ...

  2. 【Python之路】特别篇--Python装饰器

    前情提要 1. 作用域 在python中,函数会创建一个新的作用域.python开发者可能会说函数有自己的命名空间,差不多一个意思.这意味着在函数内部碰到一个变量的时候函数会优先在自己的命名空间里面去 ...

  3. 【Python之路】特别篇--Bottle

    Bottle Bottle是一个快速.简洁.轻量级的基于WSIG的微型Web框架,此框架只由一个 .py 文件,除了Python的标准库外,其不依赖任何其他模块. Bottle框架大致可以分为以下部分 ...

  4. NTT 练习

    一 . Rikka with Subset  题目: http://acm.hdu.edu.cn/showproblem.php?pid=5829 参考  https://blog.csdn.net/ ...

  5. linux vmware 安装步骤

    一.下载vmware软件 二.下载centos镜像文件 三.安装步骤 以上相当于于硬件设备已经准备ok,接下来安装软件

  6. JS将后台获取毫秒数转换为自定义格式日期

    重写prototype  Date.prototype.Format = function(fmt) { var o = { "M+" : this.getMonth()+1, / ...

  7. php执行方式对比:mod_php&php-fpm

    mod_php 1.是apache的附属包,apache死掉后php也会死掉 2.稳定性差,php出错服务器进程也会受影响 php-fpm       1.和nginx是两个独立的个体. 2.php- ...

  8. LC 672. Bulb Switcher II

    There is a room with n lights which are turned on initially and 4 buttons on the wall. After perform ...

  9. Cookie实战案例代码

    import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import javax.s ...

  10. Android百分比支持布局库的使用和源码分析

    Android-percent-support这个库 描述下这个support-lib. 这个库提供了: 两种布局供大家使用: PercentRelativeLayout.PercentFrameLa ...