题目
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.
分析
乍看到这个题目我还以为是个图的最小路径问题,受到先入为主的影响,我dijkstra算法求解,后来运行超出时间限制,因为其算法复杂度高达O(n^2xm),其代码如下:
class Solution{
public:
int minPathSum(vector<vector<int> >& grid){
int n = grid.size();
int m = grid[0].size();
vector<vector<pair<int,bool> > > pv(n,vector<pair<int,bool> >(m,make_pair(2147483647,false)));
pv[0][0].first = grid[0][0];
set<pair<int,int> > s;
s.insert(make_pair(0,0));
while (true)
{
pair<int,int> min = make_pair(n-1,m-1);
set<pair<int,int> >::iterator minp = s.begin();
for (set<pair<int,int> >::iterator p = s.begin();p!=s.end();p++)
if ((!pv[p->first][p->second].second) && pv[p->first][p->second].first < pv[min.first][min.second].first)
{
min.first = p->first;
min.second = p->second;
minp = p;
}
if (min.first == n-1 && min.second == m-1)
return pv[n-1][m-1].first;
pv[min.first][min.second].second = true;
s.erase(minp);
if (min.second < m - 1 && pv[min.first][min.second+1].second == false)
if (pv[min.first][min.second].first + grid[min.first][min.second+1] < pv[min.first][min.second+1].first)
{
pv[min.first][min.second+1].first = pv[min.first][min.second].first + grid[min.first][min.second+1];
s.insert(make_pair(min.first,min.second+1));
}
if (min.first < n - 1 && pv[min.first+1][min.second].second == false)
if (pv[min.first][min.second].first + grid[min.first+1][min.second] < pv[min.first+1][min.second].first)
{
pv[min.first+1][min.second].first = pv[min.first][min.second].first + grid[min.first+1][min.second];
s.insert(make_pair(min.first+1,min.second));
}
}
}
};
可见代码冗长且复杂度高
后来在参考了别人的思想之后才发现这是一个典型的动态规划问题,假设到达(i,j)的最小路径和为S[i][j],则状态转移方程为S[i][j] = min(S[i-1][j],S[i][j-1])+grid[i][j]。需要
注意的是边界问题,代码如下:
class Solution {
public:
int minPathSum(vector<vector<int>>& grid) {
int m = grid.size();
int n = grid[0].size();
vector<int> cur(m, grid[0][0]);
for (int i = 1; i < m; i++)
cur[i] = cur[i - 1] + grid[i][0];
for (int j = 1; j < n; j++) {
cur[0] += grid[0][j];
for (int i = 1; i < m; i++)
cur[i] = min(cur[i - 1], cur[i]) + grid[i][j];
}
return cur[m - 1];
}
};
简洁而直观,并且复杂度降低了一个数量级。