给定一个由非负整数填充的m x n的二维数组,现在要从二维数组的左上角走到右下角,请找出路径上的所有数字之和最小的路径。
注意:你每次只能向下或向右移动。
注意:你每次只能向下或向右移动。
import java.util.Arrays;
public class Solution {
public int minPathSum(int[][] grid) {
if (grid == null) {
return 0;
}
int rowLen = grid.length;
int colLen = grid[0].length;
int[] res = new int[colLen + 1];
Arrays.fill(res, Integer.MAX_VALUE);
res[1] = 0;
for (int i = 1; i <= rowLen; i++) {
for (int j = 1; j <= colLen; j++) {
//当前点的最小路径和为 : 从左边和上边选择最小的路径和再加上当前点的值
//res[j]没更新之前就表示i-1行到第j个元素的最小路径和
//因为是从左往右更新,res[j-1]表示i行第j-1个元素的最小路径和
res[j] = Math.min(res[j], res[j - 1]) + grid[i - 1][j - 1];
}
}
return res[colLen];
}
}
class Solution {
public:
// 空间复杂度哦(m*n)
int minPathSum(vector<vector<int> > &grid)
{
int m=grid.size(),n=grid[0].size();
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
if(i==0 && j!=0) grid[i][j] += grid[i][j-1];
if(i!=0 && j==0) grid[i][j] += grid[i-1][j];
if(i*j!=0)
grid[i][j] += min(grid[i-1][j],grid[i][j-1]);
}
}
return grid[m-1][n-1];
}
};
package dp;
/**
minimum-path-sum
题目描述
Given a m x n grid filled with non-negative numbers,
find a path from top left to bottom right which minimizes the sum of all numbers along its path.
Note: You can only move either down or right at any point in time.
*/
public class Minimumpathsum {
public int minPathSum(int[][] grid) {
int m = grid.length;
int n = grid[0].length;
int[][] dp = new int[m][n];
dp[0][0] = grid[0][0];
//第一行
for (int i = 1; i < n; i++) {
dp[0][i] = dp[0][i-1] + grid[0][i];
}
//第一列
for (int i = 1; i < m; i++) {
dp[i][0] = dp[i-1][0] + grid[i][0];
}
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
dp[i][j] = Math.min(dp[i-1][j], dp[i][j-1]) + grid[i][j];
}
}
return dp[m-1][n-1];
}
}
//方法二,DP参考各位大佬。class Solution {
就在原数组上dp 连新数组都不用开
int minPathSum(vector<vector<int> > &grid) {
int row = grid.size(), col = grid[0].size();
for(int i = 1; i < row; i++) grid[i][0] += grid[i-1][0];
for(int i = 1; i < col; i++) grid[0][i] += grid[0][i-1];
for(int i = 1; i < row; i++)
for(int j = 1; j < col; j++)
grid[i][j] += min(grid[i][j-1], grid[i-1][j]);
return grid[row-1][col-1];
}
class Solution {
public:
int minPathSum(vector<vector<int> > &grid) {
if(grid.empty()){
return 0;
}
int m = grid.size();
int n = grid[0].size();
vector<vector<int>> F(grid);
for(int i = 1; i < m; ++i){
F[i][0] = F[i - 1][0] +F[i][0];
}
for(int j = 1; j < n; ++j){
F[0][j] = F[0][j - 1] +F[0][j];
}
for(int i = 1; i < m; ++i){
for(int j = 1; j < n; ++j){
F[i][j] = min(F[i - 1][j], F[i][j - 1]) + F[i][j];
}
}
return F[m - 1][n - 1];
}
};
public class Solution{
//先对最左一列和最上一行特殊处理,因为这样的一列和一行中每个元素的来路只有一条,它是固定的。
//然后剩下的内层的矩形框中,每个元素的来路可能来自于左面元素,也有可能来自于上面元素。再加上
//当前元素值就是走到该位置经历的路径最小和
public int minPathSum(int[][] grid) {
int m=grid.length;
int n=grid[0].length;
if(m==0||n==0){
return 0;
}
int[][] minimumPathSum=new int[m][n];
minimumPathSum[0][0]=grid[0][0];
for (int i=1;i<m;i++){
minimumPathSum[i][0]=grid[i][0]+minimumPathSum[i-1][0];
}//lie
for (int j=1;j<n;j++){
minimumPathSum[0][j]=grid[0][j]+minimumPathSum[0][j-1];
}
for (int i=1;i<m;i++){
for (int j=1;j<n;j++){
minimumPathSum[i][j]=Math.min(minimumPathSum[i][j-1],minimumPathSum[i-1][j])+grid[i][j];
}
}
return minimumPathSum[m-1][n-1];
}
} class Solution {
public:
int minPathSum(vector<vector<int> > &grid) {
int row=grid.size();
int col=grid[0].size();
for(int i=1;i<row;i++)
grid[i][0]+=grid[i-1][0];//第一列加上方
for(int j=1;j<col;j++)
grid[0][j]+=grid[0][j-1];//第一行加左侧
for(int i=1;i<row;i++)
for(int j=1;j<col;j++)
grid[i][j]+=min(grid[i-1][j],grid[i][j-1]);//加上方和左侧中的较小值
return grid[row-1][col-1];
}
};
class Solution {
public:
int minPathSum(vector<vector<int> > &grid) {
int m = grid.size();
int n = grid[0].size();
for(int i = 0; i < m; ++i){
if(i-1 >= 0)
grid[i][0] += grid[i-1][0];
for(int j = 1; j < n; ++j){
if(i-1 >= 0)
grid[i][j] += min(grid[i-1][j], grid[i][j-1]);
else grid[i][j] += grid[i][j-1];
}
}
return grid[m-1][n-1];
}
};
public class Solution {
public int minPathSum(int[][] grid) {
if(grid == null || grid.length == 0 || grid[0].length == 0){
return 0;
}
for(int i = 0 ; i < grid.length ; i++){
for(int j = 0 ; j <grid[0].length ; j++){
grid[i][j] += i==0?(j==0?0:grid[i][j-1]):(j==0?grid[i-1][j]:Math.min(grid[i-1][j],grid[i][j-1]));
}
}
return grid[grid.length-1][grid[0].length-1];
}
}
class Solution(object): def minPathSum(self, grid): n = len(grid) m = len(grid[0]) dp = [[0] * m for i in range(n)] for i in range(n): for j in range(m): if i == 0 and j == 0: dp[i][j] = grid[i][j] elif i == 0 and j != 0: dp[i][j] = dp[i][j - 1] + grid[i][j] elif i != 0 and j == 0: dp[i][j] = dp[i - 1][j] + grid[i][j] else: dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j] return dp[-1][-1]
class Solution {
public:
int minPathSum(vector<vector<int> > &grid) {
int m = grid.size();
int n = grid[0].size();
int dp[m][n];
dp[0][0] = grid[0][0];
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
if(i==0 && j!=0)
dp[i][j] = dp[i][j-1] + grid[i][j];
else if(j==0 && i!=0)
dp[i][j] = dp[i-1][j] + grid[i][j];
else if(i*j != 0)
dp[i][j] = min(dp[i-1][j]+grid[i][j] , dp[i][j-1]+grid[i][j]);
}
}
return dp[m-1][n-1];
}
}; public class Solution {
public int minPathSum(int[][] grid) {
for (int i = 1; i < grid.length; i ++ ) {
grid[i][0] += grid[i - 1][0];
}
for (int i = 1; i < grid[0].length; i ++ ) {
grid[0][i] += grid[0][i - 1];
}
for (int i = 1; i < grid.length; i ++ ) {
for (int j = 1; j < grid[0].length; j ++ ) {
grid[i][j] += grid[i - 1][j] > grid[i][j - 1] ? grid[i][j - 1] : grid[i - 1][j];
}
}
return grid[grid.length - 1][grid[0].length - 1];
}
}
package alex.suda.leetcode;
public class MinPathSum {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
}
public static int minPathSum(int[][] grid) {
int m = grid.length;
int n = grid[0].length;
int[][] dp = new int[m][n];//dp[i][j]表示达到(i,j)位置时,最小的路径和
//初始化
dp[0][0] = grid[0][0];
for(int i=1;i<m;i++){
dp[i][0] = dp[i-1][0] + grid[i][0];
}
for(int j=1;j<n;j++){
dp[0][j] = dp[0][j-1] + grid[0][j];
}
for(int i=1;i<m;i++){
for(int j=1;j<n;j++){
dp[i][j] = Math.min(dp[i-1][j] + grid[i][j], dp[i][j-1] + grid[i][j]);
}
}
return dp[m-1][n-1];
}
}
public class Solution {
public int minPathSum(int[][] grid) {
int m=grid.length;//行数
int n=grid[0].length;//列数
int temp=0;
if(m==1){//当只有一行的情况
for(int i=0;i<n;i++){
temp+=grid[0][i];
}
return temp;
}
if(n==1){//当只有一列的情况
for(int i=0;i<m;i++){
temp+=grid[i][0];
}
return temp;
}
//二维数组动态规划仅需要一维空间大小
int[] sum = new int[n];//sum[i]代表当前节点的上方节点总路径值
sum[0]=grid[0][0];
for(int i=1;i<n;i++){//先计算第一行的路径值
sum[i]=sum[i-1]+grid[0][i];
}
temp=0;//代表当前节点的左节点总路径值
for(int i=1;i<m;i++){
temp=grid[i][0]+sum[0];
sum[0]=temp;
for(int j=1;j<n;j++){
sum[j]=grid[i][j]+min(temp,sum[j]);
temp=sum[j];
}
}
return temp;
}
int min(int x,int y){
return x<y?x:y;
}
}
class Solution
{
public:
int minPathSum(vector<vector<int> > &grid)
{
int a=grid.size(),b=grid[0].size();
for(int i=1;i<a;++i)grid[i][0]=grid[i][0]+grid[i-1][0];
for(int i=1;i<b;++i)grid[0][i]=grid[0][i]+grid[0][i-1];
for(int i=1;i<a;++i)
for(int j=1;j<b;++j)
grid[i][j]=grid[i][j]+min(grid[i-1][j],grid[i][j-1]);
return grid[a-1][b-1];
}
};
public class Solution {
public int minPathSum(int[][] grid) {
if(grid==null||grid.length==0)
return 0;
for(int j = 1;j<grid[0].length;j++)
grid[0][j] += grid[0][j-1];
if(grid.length==1)
return grid[0][grid[0].length-1];
for(int i = 1;i<grid.length;i++){
for(int j = 0;j<grid[i].length;j++){
int cost = j==0?grid[i-1][j]:Math.min(grid[i-1][j], grid[i][j-1]);
grid[i][j] += cost;
}
}
return grid[grid.length-1][grid[0].length-1];
}
}
class Solution {
public:
int minPathSum(vector<vector<int> > &grid) {
int m=grid.size(),n=grid[0].size();
vector<vector<int>> dp(m,vector<int>(n,0));
dp[0][0]=grid[0][0];
for(int j=1;j<n;++j)
dp[0][j]=dp[0][j-1]+grid[0][j];
for(int i=1;i<m;++i)
dp[i][0]=dp[i-1][0]+grid[i][0];
for(int i=1;i<m;++i){
for(int j=1;j<n;++j){
dp[i][j]=min(dp[i-1][j],dp[i][j-1])+grid[i][j];
}
}
return dp[m-1][n-1];
}
};