Longest Increasing Path in a Matrix - LeetCode

Longest Increasing Path in a Matrix - LeetCode

题目
Given an integer matrix, find the length of the longest increasing path.
From each cell, you can either move to four directions: left, right, up or down. You may NOT move diagonally or move outside of the boundary (i.e. wrap-around is not allowed).

nums = [
[9,9,4],
[6,6,8],
[2,1,1]
]
Return 4
The longest increasing path is [1, 2, 6, 9].


想法比较简单,用一个与nums一样大的二维数组a存储结果,a[i][j]表示到达nums[i][j]这个位置的最长路径的长度。
一开始把a中所有元素设置成1(自己到达自己,长度是1),然后便利整个数组,如果nums[i][j]比它上方的数大,那么a[i][j]=a[i-1][j]+1(从nums[i-1][j]可以往下走一格),下、左、右这三个方向同理,从4个方向算出的结果中选出一个最大的,作为a[i][j]的值。
这样一直迭代下去,直到a中所有数不再变化。

代码:

class Solution {
public:
    int longestIncreasingPath(vector< vector<int> >& matrix) {
        int m,n;
        m = matrix.size();
        if (m == 0) return 0;
        n = matrix[0].size();
        if (n == 0) return 0;
        vector< vector<int> > vv(m+1, vector<int>(n+1, 1));
        // cout << 1111 << endl;
        int temp, mmx = 0;
        bool flag = true;
        while (flag) {
            flag = false;
            for (int i = 0; i < m; i++) {
                for (int j = 0; j < n; j++) {
                    temp = vv[i][j];
                    if (i-1 >= 0 && matrix[i][j] < matrix[i-1][j]) vv[i][j] = max(vv[i][j], vv[i-1][j]+1);
                    if (j+1 < n && matrix[i][j] < matrix[i][j+1]) vv[i][j] = max(vv[i][j], vv[i][j+1]+1);
                    if (i+1 < m && matrix[i][j] < matrix[i+1][j]) vv[i][j] = max(vv[i][j], vv[i+1][j]+1);
                    if (j-1 >= 0 && matrix[i][j] < matrix[i][j-1]) vv[i][j] = max(vv[i][j], vv[i][j-1]+1);
                    if (vv[i][j] != temp) flag = true;
                    mmx = max(mmx, vv[i][j]);
                }
            }
        }
        return mmx;
    }
};

比较一下别人的代码又会发现自己的有多蠢

class Solution {
public:
    int longestIncreasingPath(vector<vector<int>>& matrix) {
        int rows = matrix.size();
        if (!rows) return 0;
        int cols = matrix[0].size();

        vector<vector<int>> dp(rows, vector<int>(cols, 0));
        std::function<int(int, int)> dfs = [&] (int x, int y) {
            if (dp[x][y]) return dp[x][y];
            vector<vector<int>> dirs = {{-1, 0}, {1, 0}, {0, 1}, {0, -1}};
            for (auto &dir : dirs) {
                int xx = x + dir[0], yy = y + dir[1];
                if (xx < 0 || xx >= rows || yy < 0 || yy >= cols) continue;
                if (matrix[xx][yy] <= matrix[x][y]) continue;
                dp[x][y] = std::max(dp[x][y], dfs(xx, yy));
            }
            return ++dp[x][y];
        };

        int ret = 0;
        for (int i = 0; i < rows; ++i) {
            for (int j = 0; j < cols; ++j) {
                ret = std::max(ret, dfs(i, j));
            }
        }

        return ret;
    }
};

这是用了dfs+动态规划,对每个节点用一次dfs,找出到达这个节点的最大递增路径长度。dfs会产生很多中间结果,比如说我们要求dp[i][j],那么我们必须先求出dp[i][j-1](如果这个位置没有越界的话),这就是一个中间结果,而用dfs求出的dp[i][j-1]就是到达[i][j-1]这个位置的最大递增路径长度,所以可以把它记录下来,再次遇到的时候直接返回保存的值即可

猜你喜欢

转载自blog.csdn.net/sgafpzys/article/details/78827504