leetcode542 01矩阵
给定一个由 0 和 1 组成的矩阵,找出每个元素到最近的 0 的距离。
分析:很容易想到dp[i][j] = min(dp[i-1][j], dp[i][j+1], dp[i+1][j], dp[i][j-1]),出口是若m[i][j] = 0,则dp[i][j]=0。但是有个问题,两个相邻的1,求当前值需要知道另一个,求另一个需要当前值,这样不无限循环了吗。
仔细想一个,我们可以加一个序。离当前1最近的0只可能出现在四个象限,可以分别求出每个象限的(有了秩序),再取min.
class Solution { public: vector<vector<int>> updateMatrix(vector<vector<int>>& matrix) { //if(matrix.size() == 0) reutrn vector; int n = matrix.size(), m = matrix[0].size(); vector<vector<int>>d(n, vector<int>(m, -1)); vector<vector<int>>vis(n, vector<int>(m, 0)); for(int i = 0;i < n;i++) for(int j = 0;j < m;j++) dp(i, j, d, matrix); return d; } int dp(int x, int y, vector<vector<int>>&d, vector<vector<int>>& matrix) { int& res = d[x][y]; if(res != -1) return res; if(matrix[x][y] == 0) return res=0; res = 0x3f3f3f3f; int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1}; int n = matrix.size(), m = matrix[0].size(); for(int i = 0;i < 4;i++) { int xx = x + dx[i], yy = y + dy[i]; if(xx >= 0 && xx < n && yy >= 0 && yy < m) { cout << xx << " " << yy << endl; res = min(res, dp(xx, yy, d, matrix)+1); } } return res; } };
leetcode329 矩阵中的最长递增路径
分析:同样是四个方向取min,但是这里不需要考虑相互依赖,因为本身就有递增的限制。出口就是局部最大值,其最大路径长度为1.
class Solution { public: int longestIncreasingPath(vector<vector<int>>& matrix) { if(matrix.size() == 0) return 0; int n = matrix.size(), m = matrix[0].size(); vector<vector<int>>dp(n, vector<int>(m, 0)); int ans = -1; for(int i = 0;i < n;i++) for(int j = 0;j < m;j++) { ans = max(ans, dfs(i, j, dp, matrix)); } return ans; } //dp[i][j] 表示以(i,j)开始的最长递增路径长度 int dfs(int x, int y, vector<vector<int>>& dp, vector<vector<int>>& matrix) { int& res = dp[x][y]; if(res) return res; res = 1; int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1}; int n = matrix.size(), m = matrix[0].size(); for(int i = 0;i < 4;i++) { int xx = x + dx[i], yy = y + dy[i]; if(xx >= 0 && xx < n && yy >= 0 && yy < m && matrix[xx][yy] > matrix[x][y]) { res = max(res, dfs(xx, yy, dp, matrix)+1); } } return res; } };
leetcode1091 二进制矩阵中的最短路径
分析:给定了起点和终点,直接用bfs求最短路即可。
class Solution { public: struct Point{ int x, y; Point(int x, int y) : x(x), y(y){} }; int shortestPathBinaryMatrix(vector<vector<int>>& grid) { int n = grid.size(), m = grid[0].size(); vector<vector<bool>>vis(n, vector<bool>(m, 0)); queue<pair<int, Point>>q; if(grid[0][0] != 0) return -1; vis[0][0] = true; q.push(make_pair(1, Point(0, 0))); while(!q.empty()) { auto p = q.front();q.pop(); if(p.second.x == n-1 && p.second.y == m-1) // 出口 { return p.first; } //cout << p.first << " " << p.second.x << " " << p.second.y << endl; int dx[] = {-1, -1, 0, 1, 1, 1, 0, -1}; int dy[] = {0, 1, 1, 1, 0, -1, -1, -1}; for(int i = 0;i < 8;i++) { int x = p.second.x + dx[i], y = p.second.y + dy[i]; //cout << x << " " << y << endl; if(x >= 0 && x < n && y >= 0 && y < m && grid[x][y] == 0 && vis[x][y] == false) { vis[x][y] = true; q.push(make_pair(p.first+1, Point(x, y))); } } } return -1; } };