Leetcode_dp 221. 最大正方形 322. 零钱兑换

 

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)位置为右下小的正方形的最大边长的平方 

Leetcode_dp 221. 最大正方形 322. 零钱兑换_第1张图片

 

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];
    }
};

 

 

 

你可能感兴趣的:(leetcode)