带有备忘录的DFS(同时起到防止重复访问的作用)

1 介绍

        参考之前的链接:深度优先(DFS)_hclbeloved的博客-CSDN博客

深度优先为了防止重复访问,需要一个visited数组来记录之前已经走过的路,从而起到防止走回头路的作用。现有个题目在DFS中使用到了备忘录(类似于从上到下的动态规划中的备忘录)。

        注意:从上到下的动态规划使用的也是递归,而DFS使用的也是递归。

2 矩阵中的最长递增路径

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

剑指 Offer II 112. 最长递增路径

2.1 传统的DFS求解

class Solution {
public:
    int longestIncreasingPath(vector<vector<int>>& matrix) {
        // 方法一:使用传统的DFS超出时间限制
        int n = matrix.size(), m = matrix[0].size();
        vector<vector<bool>> visited(n, vector<bool>(m, false));

        int maxLength = 0;
        for (int i=0;i<n;++i)
        {
            for (int j=0;j<m;++j)
            {
                maxLength = std::max(maxLength, dfs(matrix, i, j, 1, memo));
            }
        }

        return maxLength;        
    }
};

    int dfs(vector<vector<int>>& matrix, int r, int c, int count, vector<vector<bool>>& visited)
    {
        if (visited[r][c])
            return count;

        visited[r][c] = true;
        int maxLength = count;
        vector<pair<int,int>> neighbours{{-1,0},{1,0},{0,-1},{0,1}};
        int n = matrix.size(), m = matrix[0].size();
        for (auto& item : neighbours)
        {
            int x = r + item.first, y = c + item.second;
            if (x < 0 || x >= n || y < 0 || y >= m || matrix[x][y] <= matrix[r][c])
                continue;                
            
            maxLength = std::max(maxLength, dfs(matrix, x, y, count+1, visited));            
        }
        visited[r][c] = false;

        return maxLength;
    }

2.2 带有备忘录的DFS求解

class Solution {
public:
    int longestIncreasingPath(vector<vector<int>>& matrix) {
        // 方法二:使用带有备忘录的DFS
        int n = matrix.size(), m = matrix[0].size();
        vector<vector<int>> memo(n, vector<int>(m, 0));

        int maxLength = 0;
        for (int i=0;i<n;++i)
        {
            for (int j=0;j<m;++j)
            {
                maxLength = std::max(maxLength, dfs(matrix, i, j, memo));
            }
        }

        return maxLength;
    }
};

    //带有备忘录的DFS,同时备忘录起到了判断重复访问的作用
    /* 链接:https://leetcode-cn.com/problems/longest-increasing-path-in-a-matrix/solution/ju-zhen-zhong-de-zui-chang-di-zeng-lu-jing-by-le-2/ 
    如果使用朴素深度优先搜索,时间复杂度是指数级,会超出时间限制,因此必须加以优化。
    朴素深度优先搜索的时间复杂度过高的原因是进行了大量的重复计算,同一个单元格会被访问多次,每次访问都要重新计算。
    由于同一个单元格对应的最长递增路径的长度是固定不变的,因此可以使用记忆化的方法进行优化。用矩阵 memo 作为缓存矩阵,已经计算过的单元格的结果存储到缓存矩阵中。

    使用记忆化深度优先搜索,当访问到一个单元格 (i,j) 时,如果 memo[i][j]!=0,说明该单元格的结果已经计算过,则直接从缓存中读取结果;
    如果 memo[i][j]=0,说明该单元格的结果尚未被计算过,则进行搜索,并将计算得到的结果存入缓存中。

    遍历完矩阵中的所有单元格之后,即可得到矩阵中的最长递增路径的长度。
    */
    int dfs(vector<vector<int>>& matrix, int r, int c, vector<vector<int>>& memo)
    {
        if (memo[r][c])
            return memo[r][c];

        ++memo[r][c];
        vector<pair<int,int>> neighbours{{-1,0},{1,0},{0,-1},{0,1}};
        int n = matrix.size(), m = matrix[0].size();
        for (auto& item : neighbours)
        {
            int x = r + item.first, y = c + item.second;
            if (x < 0 || x >= n || y < 0 || y >= m || matrix[x][y] <= matrix[r][c])
                continue;              
            
            memo[r][c] = std::max(memo[r][c], 1 + dfs(matrix, x, y, memo));            
        }

        return memo[r][c];
    }

3

4

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值