LeetCode每日一题(中等)2684. 矩阵中移动的最大次数

文章讨论了一个动态规划问题,最初使用递归解法导致时间复杂度过高而超时。为了解决这个问题,文章介绍了如何将递归转换为递推,通过创建f数组并从右到左进行状态转移,同时调整边界条件。最终给出优化后的代码,实现了效率的提升。
摘要由CSDN通过智能技术生成

此题为动态规划问题,首先想到的是递归,写一个dfs(i,j),枚举出向右边的三个方向走,对应的格子没有出界且格子的值大于grid[i][j],就有

dfs(i,j) = max(dfs(i-1,j+1) +1 , dfs(i,j+1) + 1, dfs(i+1,j+1)+1)

但此方法的时间复杂度为O(m*n),会超时,代码如下:

// class Solution {
// public:
//     int maxMoves(vector<vector<int>>& grid) {
//         int res = 0 ;
//         for(int i = 0; i < grid.size(); i++)
//         {
//             res = max(res,dfs(i,0,grid));
//         }
//         return res;
//     }

//     int dfs(int i, int j, vector<vector<int>> grid)
//     {
//         if(j == grid[0].size()-1 ) return 0;
//         int res = 0;
//         int w = 0, q = 0;
//         for(int p = i-1; p < i+2; p++)
//         {
//             if(0 <= p && p <grid.size())
//             {
//                 w = grid[p][j+1];
//                 q = grid[i][j];
//                 if(w > q) 
//                 res = max(res,dfs(p,j+1,grid)+1);
//             }
//                 //if(int(grid[p][j+1]) > int())          
//         }
//         return res;
//     }
// };

为解决这个问题,将递归改为递推,参考视频动态规划入门:从记忆化搜索到递推【基础算法精讲 17】_哔哩哔哩_bilibilij状态定义和状态转移方程一直是很多同学的学习难点和痛点,今天这节课就教大家如何用递归来启发思考。涉及到的力扣题目+代码:198. 打家劫舍 https://leetcode.cn/problems/house-robber/solutions/2102725/ru-he-xiang-chu-zhuang-tai-ding-yi-he-zh-1wt1/课后作业:70. 爬楼梯 https://leet, 视频播放量 39906、弹幕量 39、点赞数 1135、投硬币枚数 766、收藏人数 1418、转发人数 117, 视频作者 灵茶山艾府, 作者简介 算法讲师 | 力扣竞赛 Top10 | 全网刷题量 7000+,相关视频:10分钟彻底搞懂“动态规划”算法,动态规划,本题关键在于理解递推公式!| LeetCode:343. 整数拆分,动态规划入门50题,《算法零基础入门》动态规划 (一),动态规划DP0-1背包,10分钟学会哈希表,带你学透0-1背包问题!| 关于背包问题,你不清楚的地方,这里都讲了!| 动态规划经典问题 | 数据结构与算法,刷了1000多道算法题,分享我的心得。希望这个视频能帮助你学习算法、坚持下来,【喵的算法课】动态规划 01背包【3期】,我是如何因为算法竞赛毁掉自己人生的https://www.bilibili.com/video/BV1Xj411K7oF/?vd_source=ebbdf39d84de3a610b43c756d51769dc

 需要三步完成:

1.将dfs改为f数组

2.递归改为循环,由于递归是从左向右移动,所以递推是从右到左移动。

3.递归的边界改为f数组的初始值。

代码如下所示:

class Solution {
public:
    int maxMoves(vector<vector<int>>& grid) {
        int m = grid.size(), n = grid[0].size();
        int res = 0 ;
        int w = 0, q = 0;
        int f[m][n];
        memset(f,0,sizeof(f));

        for(int j = n -2; j >= 0; j--)
            for(int i = 0; i < m; i++)
                for(int p = max(i-1, 0); p < min(i+2, m); p++)
                {
                    if(grid[p][j+1] > grid[i][j]) 
                        f[i][j] = max(f[i][j],f[p][j + 1] + 1);    
                }
       
        int ans = 0;
        for(int i=0; i<m; i++)
            ans = max(ans,f[i][0]);
        return ans;
    }

    
};

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值