[LeetCode] 329. 矩阵中的最长递增路径

329. 矩阵中的最长递增路径

给定一个整数矩阵,找出最长递增路径的长度。

对于每个单元格,你可以往上,下,左,右四个方向移动。 你不能在对角线方向上移动或移动到边界外(即不允许环绕)。

在这里插入图片描述
解题思路: 虽然此题标记的难度是难,但是设计好了图遍历的函数形式,解此题不太难,之前做题,尤其是做与路径统计的极值问题时,会发现设计一个号的函数形式,具体的说,是函数的形参和返回值的物理涵义,会非常有利于打开解题的思路。题目要求的是醉成递增路径,那么我们先分析一下,所有的路径一定是以图中某个点为起点,然后向四周延展,那么我们可以遍历每一个点,以这个点为起点,记录这个路径最长能达到多长,即可遍历完图中所有的路径,然后需要解决的是如何求以这个节点出发的最长路径,路径的延展无非是向四个方向进行,那么我在判定当前这个节点最长路径时,只需要前确定与这个节点相邻的四个节点中最长路径即可,然后这个最长路径加1即为当前节点出发的最长路径,OK,至此,此题的思路应该就比较明晰了,函数的返回值肯定是设计为当前节点的最长路径值。由于图的遍历是近乎暴力解法,对其中一个节点遍历时,又会把四周节点的路径值重复求一遍,这个会存在大量的重复计算,因此可以借助记忆数组,避免重复计算。好了,我们可以看一下此题的解题代码。

// 标签:图的遍历+记忆数组
// 本题本质上是在考察图的遍历,由于图的遍历近乎暴力解法,但是此题
// 的遍历情形中存在大量重复的计算,因此可以用记忆数组保存已经遍历
// 的结果,以减少时间复杂度.
// Space: O(n),时间复杂度有点不好分析,暂不分析了
class Solution {
public:
    int helper(vector<vector<int>>& matrix, int r, int c) {
        if (m.count({r,c})) return m[{r,c}];
        int mx = 0;
        int rows = matrix.size(), cols = matrix[0].size();
        for (auto dir : dirs) {
            int x = r + dir[0], y = c + dir[1];
            if (x < 0 || x >= rows || y < 0 || y >= cols) continue;
            if (matrix[x][y] > matrix[r][c]) {
                mx = max(mx, helper(matrix, x, y));
            }
        }
        return m[{r,c}] = mx + 1;
    }
    int longestIncreasingPath(vector<vector<int>>& matrix) {
        if (matrix.empty() || matrix[0].empty()) return 0;
        int rows = matrix.size(), cols = matrix[0].size();
        int res = 0;
        for (int i = 0; i < rows; ++i) {
            for (int j = 0; j < cols; ++j) {
                res = max(res, helper(matrix, i, j));
            }
        }
        return res;
    }

private:
    map<pair<int, int>, int> m;
    vector<vector<int>> dirs = {{1,0},{-1,0},{0,1},{0,-1}};
};
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值