Given an m x n grid filled with nonnegative 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.

动态规划问题.

  1. 状态转移公式: F[i,j] = min(F[i,j-1], F[i-1,j]) + A[i,j]
  2. 最优子结构: F[i,j-1], F[i-1,j] 和 A[i,j]
  3. 边界: F[0,0] = A[0,0];

参照例子:

1 2 3 4
4 3 2 1
2 1 2 3

实现中有三种选择:

  1. 最优的: \(O(m*n)\) time, \(O(min(m, n))\) extra space;(maintain an array)
  2. 次优的: \(O(m*n)\) time, \(O(m)+O(n)\) extra space;(维护俩数组,长度分别m, n)
  3. 最差的: \(O(m*n)\) time, \(O(m*n)\) extra space.(maintain a matrix, m*n)

自个想法,自个最优空间复杂度代码:

\(O(m*n)\) time, \(O(min(m, n))\) extra space;

// method 2
// DP
// F[i,j] = min(F[i,j-1], F[i-1,j] + A[i,j])
// O(m*n) time, O(min(m,n)) extra space
int minPathSum(vector<vector<int>>& A) {
const int m = A.size(), n = A[0].size();
if (m == 0) return 0;
if (m == 1 && n == 1) return A[0][0]; vector<int> dp(n); // load the 0st row of A into dp
dp[0] = A[0][0];
for (int j = 1; j < n; j++)
dp[j] = A[0][j] + dp[j - 1]; // fill none first row and col in dp by state transfer equation
for (int i = 1; i < m; i++) {
for (int j = 0; j < n; j++) {
if (j == 0) dp[j] = dp[j] + A[i][0];
else dp[j] = min(dp[j - 1], dp[j]) + A[i][j];
}
}
return dp[n - 1];
}

自个想法,自个差空间复杂度代码:

\(O(m*n)\) time, \(O(m*n)\) extra space;

// method 1
// DP
// F[i,j] = min(F[i,j-1], F[i-1,j]) + A[i,j]
// O(m*n) time, O(m*n) extra space
// not good
int minPathSum(vector<vector<int>>& A) {
const int m = A.size(), n = A[0].size();
if (m == 0) return 0;
if (m == 1 && n == 1) return A[0][0]; // initialize dp(m*n) matrix
vector < vector<int> > dp(m);
for (int i = 0; i < m; i++)
dp[i].resize(n); // fill first row in dp
dp[0][0] = A[0][0];
for (int j = 1; j < n; j++)
dp[0][j] = A[0][j] + dp[0][j - 1]; // fill first col in dp
for (int i = 1; i < m; i++)
dp[i][0] = A[i][0] + dp[i - 1][0]; // fill none first row and col in dp by state transfer equation
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
dp[i][j] = min(dp[i][j - 1], dp[i - 1][j]) + A[i][j];
}
}
return dp[m - 1][n - 1];
}

随机推荐

  1. 新概念英语(1-135)The latest report

    Lesson 135 The latest report 最新消息 Listen to the tape then answer this question. Is Karen Marsh going ...

  2. jquery-模仿qq提示消息

    ( function() { var ua = navigator.userAgent.toLowerCase(); var is = (ua.match(/\b(chrome|opera|safar ...

  3. jscript定时器,一直用的东西,你真的明白吗?

    JavaScript定时器 JavaScript是一种解释型语言(边编译边执行),Js解析顺序是从上到下,然后将编译后的任务丢到一个事件队列中,然后事件内的函数会从上到下开始执行 setInterva ...

  4. Codeforces 343D WaterTree - 线段树, DFS序

    Description Translated by @Nishikino_Maki from Luogu 行吧是我翻的 Mad scientist Mike has constructed a roo ...

  5. python/socket编程之粘包

    python/socket编程之粘包 粘包 只有TCP有粘包现象,UDP永远不会粘包. 首先需要掌握一个socket收发消息的原理 发送端可以是1k,1k的发送数据而接受端的应用程序可以2k,2k的提 ...

  6. sqlalchemy通过ssh连接远程mysql服务器

    首先需要一个模块sshtunnel,如果没有直接pip install sshtunnel from sshtunnel import SSHTunnelForwarder from sqlalche ...

  7. requests-模拟登陆

    import requests requests.get('http://httpbin.org/cookies/set/number/123456') response = requests.get ...

  8. 告知服务器意图的http方法

    1.GET 用来获取资源,返回已有的结果 2.POST 传输实体主体,返回处理过后的结果 3.PUT 向服务器传输文件,返回是否成功的状态码 4.DELETE 删除服务器文件,返回是否成功的状态码 5 ...

  9. transform做2d和3d变形(css动画一)

    前言:这是笔者学习之后自己的理解与整理.如果有错误或者疑问的地方,请大家指正,我会持续更新! 有段时间我是没理清transform.translate.transition和animation之间的关 ...

  10. [LeetCode] Dota2 Senate 刀塔二参议院

    In the world of Dota2, there are two parties: the Radiant and the Dire. The Dota2 senate consists of ...