329. Longest Increasing Path in a Matrix(DFS & DP)

来源:互联网 发布:福山雅治 知乎 编辑:程序博客网 时间:2024/06/05 03:44

1. 描述题目

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).

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

Example 2:
nums = [
[3,4,5],
[3,2,6],
[2,2,1]
]
Return 4
The longest increasing path is [3, 4, 5, 6]. Moving diagonally is not allowed.


2.算法及代码

解法一:使用了C++ 11的lamda函数特性
结合递归的DFS和动态规划

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));        //C++ 11 lamda函数        std::function<int(int, int)> dfs = [&](int x, int y) {            if(dp[x][y]) return dp[x][y]; // 已经访问过的元素非零,                                             //也即已经完成了递归求得dp[i][j],                                            //四个方向都不存在大于当前元素的元素             //分别是向 上、下、右、左             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];          };        // 对矩阵中的每个元素都进行DFS搜索        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,常规代码,没有lamda表达式

class Solution {public:    int longestIncreasingPath(vector<vector<int>>& matrix) {        vector<vector<int>> table;        for (int i=0; i<matrix.size(); i++) {            vector<int> cur(matrix[0].size());            for (int j=0; j<matrix[0].size(); j++) {                cur[j] = -1;            }            table.push_back(cur);        }        int path = 0;        for (int i=0; i<matrix.size(); i++) {            for (int j=0; j<matrix[0].size(); j++) {                int cur = helper(matrix, table, i, j);                if (cur > path) path = cur;            }        }        return path;    }    int helper(vector<vector<int>>& matrix, vector<vector<int>>& table, int x, int y) {        if (table[x][y] != -1) return table[x][y];        int curValue = matrix[x][y];        int up = 0;        int right = 0;        int down = 0;        int left = 0;        if (x-1 >= 0 && curValue < matrix[x-1][y]) {            if (table[x-1][y] == -1) {                table[x-1][y] = helper(matrix, table, x-1, y);            }                up = table[x-1][y];        }        if (x+1 < matrix.size() && curValue < matrix[x+1][y]) {            if (table[x+1][y] == -1) {                table[x+1][y] = helper(matrix, table, x+1, y);            }                down = table[x+1][y];        }        if (y-1 >= 0 && curValue < matrix[x][y-1]) {            if (table[x][y-1] == -1) {                table[x][y-1] = helper(matrix, table, x, y-1);            }                left = table[x][y-1];        }         if (y+1 < matrix[0].size() && curValue < matrix[x][y+1]) {            if (table[x][y+1] == -1) {                table[x][y+1] = helper(matrix, table, x, y+1);            }                right = table[x][y+1];        }        return 1 + max(max(up, down), max(left, right));    }};