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