两个矩阵中的dp题的差异

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;
    }
};
View Code

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;
    }
};
View Code

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;
    }
};
View Code

 

posted @ 2020-04-15 18:29  Rogn  阅读(256)  评论(0编辑  收藏  举报