leetcode-6110:网格图中递增路径的数目

简介: leetcode-6110:网格图中递增路径的数目

题目

题目连接

给你一个 m x n 的整数网格图 grid ,你可以从一个格子移动到 4 个方向相邻的任意一个格子。

请你返回在网格图中从 任意 格子出发,达到 任意 格子,且路径中的数字是 严格递增 的路径数目。由于答案可能会很大,请将结果对 1 0 9 + 7 10^9 + 7109+7 取余 后返回。

如果两条路径中访问过的格子不是完全相同的,那么它们视为两条不同的路径。

示例 1:

输入:grid = [[1,1],[3,4]]
输出:8
解释:严格递增路径包括:
- 长度为 1 的路径:[1],[1],[3],[4] 。
- 长度为 2 的路径:[1 -> 3],[1 -> 4],[3 -> 4] 。
- 长度为 3 的路径:[1 -> 3 -> 4] 。
路径数目为 4 + 3 + 1 = 8 。

示例 2:

输入:grid = [[1],[2]]
输出:3
解释:严格递增路径包括:
- 长度为 1 的路径:[1],[2] 。
- 长度为 2 的路径:[1 -> 2] 。
路径数目为 2 + 1 = 3 。

解题

方法一:dfs记忆化搜索

通过memory数组保存,每个格点的递增路径数目

比如memory[i][j],表示终点为(i,j)的递增路径数目

class Solution {
public:
    const int MOD=1e9+7;
    vector<vector<int>> dirs={{-1,0},{0,-1},{1,0},{0,1}};
    vector<vector<int>> memory;
    int dfs(vector<vector<int>>& grid,int i,int j){
        if(memory[i][j]>0) return memory[i][j];
        memory[i][j]=1;
        for(vector<int>& dir:dirs){
            int nx=i+dir[0];
            int ny=j+dir[1];
            if(nx<0||nx>=grid.size()||ny<0||ny>=grid[0].size()||grid[i][j]<=grid[nx][ny]) continue;
            memory[i][j]=(memory[i][j]+dfs(grid,nx,ny))%MOD;
        }
        return memory[i][j];
     }
    int countPaths(vector<vector<int>>& grid) {
        int m=grid.size();
        int n=grid[0].size();
        memory.resize(m,vector<int>(n));
        int res=0;
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                res=(res+dfs(grid,i,j))%MOD;
            }
        }
        return res;
    }
};

方法二:动态规划(超时)

dp[i][j][l]表示格点为(i,j),路径长度为l的数量,

这样做的目的是因为,只有得到长度为 l-1的路径数量,才能计算出长度为l的路径数量。

缺点:

然而比如 grid[2][3]>grid[2][4]

但是每次都会进行重复比较,遍历到(2,3),会跟右边比,遍历到(2,4)还要跟左边比,并且没法记忆化,因为dp[i][j][l]只是l长度的结果,只是一个中间值,不是最终结果。

而方法一:是直接保存了每个格点的所有递增路径数目,因此可以记忆化。(dfs,复杂度O ( n 2 ) O(n^2)O(n2)

方法二可以得到每种路径长度的数量,小量数据可以通过,但是会超时。(矩阵遍历,复杂度O ( n 3 ) O(n^3)O(n3)

class Solution {
public:
    const int Mod=1e9+7;
    vector<vector<int>> dirs={{-1,0},{0,-1},{1,0},{0,1}};
    int countPaths(vector<vector<int>>& grid) {
        int res=0;
        int m=grid.size();
        int n=grid[0].size();
        int maxPath=m*n;
        vector<vector<vector<int>>> dp(m,vector<vector<int>>(n,vector<int>(m*n+1)));
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                dp[i][j][0]=0;
                dp[i][j][1]=1;
                res++;
            }
        }
        for(int l=2;l<=maxPath;l++){
            for(int i=0;i<m;i++){
                for(int j=0;j<n;j++){
                    dp[i][j][l]=0;
                    for(vector<int>& dir:dirs){
                        int nx=i+dir[0];
                        int ny=j+dir[1];
                        if(nx>=0&&nx<m&&ny>=0&&ny<n&&grid[i][j]>grid[nx][ny]){
                            dp[i][j][l]+=dp[nx][ny][l-1];
                        }
                    }
                    res=(res+dp[i][j][l])%Mod;
                }
            }
        }
        return res;
    }
};
相关文章
|
1月前
|
存储 算法 Linux
LeetCode第71题简化路径
文章讲述了LeetCode第71题"简化路径"的解题方法,利用栈的数据结构特性来处理路径中的"."和"..",实现路径的简化。
LeetCode第71题简化路径
|
1月前
|
算法
LeetCode第64题最小路径和
LeetCode第64题"最小路径和"的解题方法,运用动态规划思想,通过构建一个dp数组来记录到达每个点的最小路径和,从而高效求解。
LeetCode第64题最小路径和
|
1月前
|
算法 JavaScript Python
【Leetcode刷题Python】79. 单词搜索和剑指 Offer 12. 矩阵中的路径
Leetcode第79题"单词搜索"的Python解决方案,使用回溯算法在给定的二维字符网格中搜索单词,判断单词是否存在于网格中。
23 4
|
1月前
|
存储 Python
【Leetcode刷题Python】滑雪路径消耗时间:Testing Round #16 (Unrated) C. Skier
Leetcode题目"Testing Round #16 (Unrated) C. Skier"的Python解决方案,题目要求计算给定滑雪路径字符串的总耗时,其中未走过的边耗时5秒,走过的边耗时1秒。
35 4
|
1月前
|
存储 Python
【Leetcode刷题Python】1496.判断路径是否相交
Leetcode第1496题"判断路径是否相交"的Python代码实现,通过使用字典存储方向和集合记录访问过的坐标点来检测路径是否与自身相交。
36 2
|
1月前
|
算法 Python
【Leetcode刷题Python】300. 最长递增子序列
LeetCode 300题 "最长递增子序列" 的两种Python解决方案:一种使用动态规划,另一种使用贪心算法结合二分查找。
29 1
|
1月前
|
机器人 Python
【Leetcode刷题Python】63. 不同路径 II
LeetCode 63题 "不同路径 II" 的Python解决方案,使用动态规划算法计算在有障碍物的网格中从左上角到右下角的不同路径数量。
20 1
|
1月前
|
算法 Java
LeetCode初级算法题:子数组最大平均数+二叉树的最小深度+最长连续递增序列+柠檬水找零
LeetCode初级算法题:子数组最大平均数+二叉树的最小深度+最长连续递增序列+柠檬水找零
33 0
|
1月前
|
Python
【Leetcode刷题Python】674. 最长连续递增序列
LeetCode 674题 "最长连续递增序列" 的Python解决方案,使用动态规划算法找出给定整数数组中最长连续递增子序列的长度。
51 0
|
1月前
|
Python
【Leetcode刷题Python】剑指 Offer 32 - III. 从上到下打印二叉树 III
本文介绍了两种Python实现方法,用于按照之字形顺序打印二叉树的层次遍历结果,实现了在奇数层正序、偶数层反序打印节点的功能。
42 6