Minimum Path Sum

来源:互联网 发布:手机word文档软件 编辑:程序博客网 时间:2024/04/29 16:01

题目

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];    }};
简洁而直观,并且复杂度降低了一个数量级。


0 0