当前位置:网站首页>leetcode-6110:网格图中递增路径的数目
leetcode-6110:网格图中递增路径的数目
2022-07-05 05:46:00 【菊头蝙蝠】
leetcode-6110:网格图中递增路径的数目
题目
给你一个 m x n
的整数网格图 grid
,你可以从一个格子移动到 4
个方向相邻的任意一个格子。
请你返回在网格图中从 任意 格子出发,达到 任意 格子,且路径中的数字是 严格递增 的路径数目。由于答案可能会很大,请将结果对 1 0 9 + 7 10^9 + 7 109+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;
}
};
边栏推荐
- Daily question - Search two-dimensional matrix PS two-dimensional array search
- 网络工程师考核的一些常见的问题:WLAN、BGP、交换机
- 读者写者模型
- Implement an iterative stack
- Zheng Qing 21 ACM is fun. (3) part of the problem solution and summary
- Detailed explanation of expression (csp-j 2021 expr) topic
- 中职网络安全技能竞赛——广西区赛中间件渗透测试教程文章
- shared_ Repeated release heap object of PTR hidden danger
- Collection: programming related websites and books
- SAP method of modifying system table data
猜你喜欢
Educational Codeforces Round 116 (Rated for Div. 2) E. Arena
Web APIs DOM node
Reader writer model
Solution to game 10 of the personal field
Full Permutation Code (recursive writing)
智慧工地“水电能耗在线监测系统”
In this indifferent world, light crying
sync. Interpretation of mutex source code
挂起等待锁 vs 自旋锁(两者的使用场合)
中职网络安全技能竞赛——广西区赛中间件渗透测试教程文章
随机推荐
【Jailhouse 文章】Jailhouse Hypervisor
Simply sort out the types of sockets
Over fitting and regularization
2022年贵州省职业院校技能大赛中职组网络安全赛项规程
每日一题-无重复字符的最长子串
Animation scoring data analysis and visualization and it industry recruitment data analysis and visualization
Chapter 6 data flow modeling - after class exercises
Transform optimization problems into decision-making problems
Daily question - Search two-dimensional matrix PS two-dimensional array search
sync. Interpretation of mutex source code
EOJ 2021.10 E. XOR tree
Pointnet++ learning
Haut OJ 1401: praise energy
[article de jailhouse] jailhouse hypervisor
Reflection summary of Haut OJ freshmen on Wednesday
wordpress切换页面,域名变回了IP地址
YOLOv5-Shufflenetv2
Dichotomy, discretization, etc
Time complexity and space complexity
【实战技能】非技术背景经理的技术管理