• 两个矩阵中的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
  • 相关阅读:
    Typora标题自动编号+设定快捷键技巧
    配置redis 4.0.11 集群
    学会使用 Mysql show processlist 排查问题
    Golang学习的方法和建议
    日志文件删除shell脚本
    运维趋势2019年总结,运维就是要做到"技多不压身"
    我的xshell配色方案,绿色/护眼/留存/备份
    对于api接口的爬虫,通常的解决方法
    maven 打包和构建的Linux命令(mvn)
    Istio的流量管理入门-charlieroro编写
  • 原文地址:https://www.cnblogs.com/lfri/p/12707183.html
Copyright © 2020-2023  润新知