LeetCode 热题 HOT 100 -------64. 最小路径和 (动态规划) 221. 最大正方形(动态规划)

dasdas在这里插入图片描述

/*动态规划: 
注意:m,n已经给了范围,所以不需要写grid.length==0.grid==null的情况
因为用动态规划所以我们要考虑边界和转移方程,转移方程可以直接用grid[]代替,
因为每次都是向下或者向右走所以只考虑上边界和左边界 dp[0][0] = grid[0][0],dp[0][j] = dp[0][j-1] + grid[0][j]
左边界:dp[i][0]=dp[i-1][0] + grid[i][0]
转移方程 dp[i][j] = Math.min(dp[i-1][j] , dp[i][j-1]) + grid[i][j]
返回值dp[m-1][n-1]
时间复杂度O(mn) 空间复杂度O(mn)
*/
class Solution {
    public int minPathSum(int[][] grid) {
       //行
       int carryLen = grid.length;
       //列
       int rowLen = grid[0].length;
       
       int[][] dp = new int[carryLen][rowLen];

       //边界
       dp[0][0] = grid[0][0];
       
       for(int i=1 ;  i<carryLen ; i++){
           dp[i][0] = dp[i-1][0] + grid[i][0];
       }
       for(int j=1 ; j<rowLen ; j++){
           dp[0][j] = dp[0][j-1] + grid[0][j];
       }

       //转移方程
       for(int i=1 ; i< carryLen ; i++){
           for(int j=1 ; j<rowLen ; j++){
               dp[i][j] = Math.min(dp[i-1][j] , dp[i][j-1]) + grid[i][j];
           }
       }
       return dp[carryLen-1][rowLen-1];
    }
}

// //进一步简化,没有必要进行创建新的dp[][],直接用给的二维数组grid[][]即可
// //时间复杂度O(mn)空间复杂度O(1)
class Solution {
    public int minPathSum(int[][] grid) {
        for(int i=0 ; i<grid.length ; i++){
            for(int j=0 ; j<grid[0].length ; j++){
                if(i==0 && j==0) continue;  //不用改变grid的值
                else if(i == 0) grid[0][j] = grid[0][j-1] + grid[i][j];
                else if(j == 0) grid[i][0] = grid[i-1][0] + grid[i][j];
                else grid[i][j] = Math.min(grid[i-1][j] , grid[i][j-1]) + grid[i][j];
            }
        }
        return grid[grid.length-1][grid[0].length-1];
    }
}

dsadsdss在这里插入图片描述
dsdsadsdss在这里插入图片描述

//两种方法,第一种我们用传统的暴力搜索
// class Solution {
//     public int maximalSquare(char[][] matrix) {
//         // 数组的行列值
//         int carryLen = matrix.length;
//         int rowLen = matrix[0].length;
//         // 最大的边长
//         int maxLen = 0;
//         // 遍历数组
//         for( int i=0 ; i<carryLen ; i++){
//             for(int j=0 ; j<rowLen ; j++){
//                 if(matrix[i][j]=='1'){
//                     maxLen = Math.max(maxLen , 1);
//                     //把每一个点看作正方形的左上角
//                     int curMaxLen = Math.min(carryLen-i , rowLen-j);
//                     //标志位
//                     boolean flag = true;
                   
//                     for(int k=1 ; k< curMaxLen ; k++){
//                          //先看对角
//                         if(matrix[i+k][j+k] == '0'){
//                             flag =false; 
//                             break;
//                         }
//                          //再看其他位置
//                         for(int m=0 ; m<k ; m++){
//                             if(matrix[i+m][j+k] == '0' || matrix[i+k][j+m] == '0'){
//                                 flag = false;
//                                 break;
//                             }
//                         }
//                         if(flag){
//                             maxLen = Math.max(maxLen, k+1);
//                         }else{
//                             break;
//                         }
//                     }
//                 }
//             }
//         }
//         return maxLen*maxLen;
//     }
// }

// 第一种方法,时间复杂度O(mn(min(m,n))^2),空间复杂度O(1),可以通过动态规划进一步化简
// dp[i][j]指的是以i,j位置为正方形的右下角
class Solution {
    public int maximalSquare(char[][] matrix) {

        //动态规划,找边界以及转移方程,把每一个点当成一个正方形的右下角
        int columns = matrix.length , rows = matrix[0].length;
        int[][] dp = new int[columns][rows]; 
        int maxSize=0;  //最大边长
        for(int i=0 ; i<columns ; i++){
            for(int j=0 ; j<rows ; j++){
                //边界
                if(matrix[i][j] == '1'){ //只有在当前节点为1的情况下才能进行下一步
                    if(i == 0 || j == 0){
                        dp[i][j] = 1;
                    }else{
                        //写转移方程(像木桶的短板理论 那样——附近的最小边长,才与 ? 的最长边长有关。)
                        dp[i][j] = Math.min(Math.min(dp[i-1][j] , dp[i][j-1]) , dp[i-1][j-1]) +1;
                    }
                    maxSize = Math.max(maxSize , dp[i][j]);
                }
            }
        }
        return maxSize*maxSize;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值