221. 最大正方形
在一个由 0 和 1 组成的二维矩阵内,找到只包含 1 的最大正方形,并返回其面积。
示例:
输入:
1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0
输出: 4
方法1.dp
这个题可以规约到85.最大矩形,dp做,就是注意求正方形面积时,边长edge=Math.min(right[j]-left[j],height[j]);
maxarea = Math.max(maxarea, edge*edge);
class Solution {
/* private int Min(int a,int b,int c){
return a>b?(c>b?b:c):(c>a?a:c);
}*/
public int maximalSquare(char[][] matrix) {
if(matrix.length == 0) return 0;
int m = matrix.length;
int n = matrix[0].length;
int[] left = new int[n]; // initialize left as the leftmost boundary possible
int[] right = new int[n];
int[] height = new int[n];
Arrays.fill(right, n); // initialize right as the rightmost boundary possible
int maxarea = 0;
for(int i = 0; i < m; i++) {
int cur_left = 0, cur_right = n;
// update height
for(int j = 0; j < n; j++) {
if(matrix[i][j] == '1') height[j]++;
else height[j] = 0;
}
// update left
for(int j=0; j= 0; j--) {
if(matrix[i][j] == '1') right[j] = Math.min(right[j], cur_right);
else {right[j] = n; cur_right = j;}
}
// update area
for(int j = 0; j < n; j++) {
int edge=Math.min(right[j]-left[j],height[j]);
maxarea = Math.max(maxarea, edge*edge);
}
}
return maxarea;
}
}
执行用时 :4 ms, 在所有 Java 提交中击败了98.90%的用户
内存消耗 :43.4 MB, 在所有 Java 提交中击败了18.75%的用户
方法2.
线性dp
状态表示:
dp[i][j] 以第ij位置为右下角的正方的最大边长
状态计算
dp[i][j] = min(dp[i-1][j], dp[i-1][j-1], dp[i][j-1]) + 1
答案:
枚举每一个第(i,j)位置为右下小的正方形的最大边长的平方
class Solution {
public:
int maximalSquare(vector>& matrix) {
if (matrix.empty() || matrix[0].empty()) return 0;
int n = matrix.size(), m = matrix[0].size();
vector> dp(n+1, vector(m+1));
int ans = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (matrix[i-1][j-1] == '1') {
dp[i][j] = min({dp[i-1][j], dp[i-1][j-1], dp[i][j-1]}) + 1;
ans = max(ans, dp[i][j]);
}
}
}
return ans * ans;
}
};
执行用时 :28 ms, 在所有 C++ 提交中击败了29.38%的用户
内存消耗 :8.9 MB, 在所有 C++ 提交中击败了100.00%的用户
322. 零钱兑换
示例 1:
输入: coins = [1, 2, 5], amount = 11
输出: 3
解释: 11 = 5 + 5 + 1
示例 2:
输入: coins = [2], amount = 3
输出: -1
15.79%
class Solution {
public:
int coinChange(vector& coins, int amount) {
int Max=amount+1;
vector dp(amount+1,Max);
for(int tmp:coins){
if(tmp<=amount) dp[tmp]=1;
}
dp[0]=0;
for(int i=1;i<=amount;i++){
for(int tmp:coins){
if(i>tmp) dp[i]=min(dp[i],dp[i-tmp]+1);
}
}
return dp[amount]==Max?-1:dp[amount];
}
};