LeetCode | 最小路径和的两种解决办法

第一种:动态规划

思路

在过去,有这样一个词,那就是遇难则反,从起点推导出最小路径和是困难的,那我们就从终点去推导。

解题过程

我们都知道一个方块,只能向右或向下。在初始化dp之后,我们会有这样一条关系式:

d p [ i ] [ j ] = { g r i d [ m − 1 ] [ n − 1 ] if  i = = m − 1   a n d   j = = n − 1 m i n ( d p [ i + 1 ] [ j ] + g r i d [ i ] [ j ] , d p [ i ] [ j + 1 ] + g r i d [ i ] [ j ] ) if  i + 1 < m   a n d   j + 1 < n m i n ( d p [ i + 1 ] [ j ] + g r i d [ i ] [ j ] , d p [ i ] [ j ] ) if  i + 1 < m m i n ( d p [ i ] [ j ] , d p [ i ] [ j + 1 ] + g r i d [ i ] [ j ] ) if   j + 1 < n dp[i][j] = \left\{\begin{matrix} grid[m-1][n-1]&\text{if } i == m-1 \ and \ j == n-1 \\ min(dp[i+1][j] + grid[i][j], dp[i][j+1] + grid[i][j])&\text{if } i+1 < m \ and \ j+1 < n \\ min(dp[i+1][j] + grid[i][j], dp[i][j])&\text{if } i+1 < m \\ min(dp[i][j], dp[i][j+1] + grid[i][j])&\text{if } \ j+1 < n \end{matrix} \right. dp[i][j]= grid[m1][n1]min(dp[i+1][j]+grid[i][j],dp[i][j+1]+grid[i][j])min(dp[i+1][j]+grid[i][j],dp[i][j])min(dp[i][j],dp[i][j+1]+grid[i][j])if i==m1 and j==n1if i+1<m and j+1<nif i+1<mif  j+1<n

复杂度

时间复杂度: O ( N ⋅ M ) O(N \cdot M) O(NM)

空间复杂度: O ( N ⋅ M ) O(N \cdot M) O(NM)

Code

class Solution {
public:
	int minPathSum(vector< vector > & grid) {
		vector> dp;
		int m = grid.size(), n = grid[0].size();
		for(int i = 1; i <= m; ++i) {
			vector t (n, INT_MAX);
			dp.push_back(t);
		}
        dp[m-1][n-1] = grid[m-1][n-1];
		for(int i = m-1; i >= 0; --i) {
            for(int j = n-1; j >= 0; --j) {
                if(i == m-1 && j == n-1) continue;
                if(i+1 < m && j+1 < n) {
                    dp[i][j] = min(dp[i+1][j] + grid[i][j], dp[i][j+1] + grid[i][j]);
                } else {
                    if(i+1 < m) {
                        dp[i][j] = min(dp[i+1][j] + grid[i][j], dp[i][j]);
                    }
                    if(j+1 < n) {
                        dp[i][j] = min(dp[i][j+1] + grid[i][j], dp[i][j]);
                    }
                }
            }
        }
		return dp[0][0];
	}
};

第二种:BFS

思路

在过去,有这样一个词,那就是遇难则反,从起点推导出最小路径和是困难的,那我们就从终点去推导。

解题过程

这个其实就是利用优化过后的bfs去解决的

复杂度

时间复杂度: O ( M n ) O(Mn) O(Mn)

空间复杂度: O ( n ) O(n) O(n)

Code

class Solution {
public:
	int minPathSum(vector< vector<int> > & grid) {
		vector<vector<int>> dp;
		int m = grid.size(), n = grid[0].size();
		for(int i = 1; i <= m; ++i) {
			vector<int> t (n, INT_MAX);
			dp.push_back(t);
		}
		int xs[3] = {-1, 0};
		int ys[3] = {0, -1};
        int MINCount = INT_MAX;
		int cury = m-1, curx = n-1;
		dp[cury][curx] = grid[cury][curx];
		queue<pair<int, int>> Q;
		Q.push({curx, cury});
		while(!Q.empty()) {
			pair<int, int> top = Q.front();
			Q.pop();
			for(int i = 0; i < 2; ++i) {
				int tx = top.first + xs[i], ty = top.second + ys[i];
				if(tx < 0 || ty < 0) continue;
                if(i == 0) {
                    if(dp[top.second][top.first] + grid[ty][tx] < dp[ty][tx]) {
                        dp[ty][tx] = dp[top.second][top.first] + grid[ty][tx];
                        Q.push({tx, ty});
                    }
                } else {
                    if(top.second+ys[0] >= 0 && top.first+xs[0] >= 0 && dp[top.second][top.first] + grid[ty][tx] < dp[top.second+ys[0]][top.first+xs[0]]) {
                        dp[ty][tx] = dp[top.second][top.first] + grid[ty][tx];
                        Q.push({tx, ty});
                    } else if(dp[top.second][top.first] + grid[ty][tx] < dp[ty][tx]) {
                        dp[ty][tx] = dp[top.second][top.first] + grid[ty][tx];
                        Q.push({tx, ty});
                    }
                }
			}
		}
		return dp[0][0];
	}
};

你可能感兴趣的:(#,LeetCode,#,蓝桥那些事,leetcode,数据结构,c++,算法,开发语言)