当前位置:网站首页>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;
}
};
边栏推荐
- 剑指 Offer 58 - II. 左旋转字符串
- ALU逻辑运算单元
- Haut OJ 2021 freshmen week II reflection summary
- 26、 File system API (device sharing between applications; directory and file API)
- Sword finger offer 09 Implementing queues with two stacks
- [practical skills] how to do a good job in technical training?
- Implement an iterative stack
- CF1637E Best Pair
- 剑指 Offer 53 - II. 0~n-1中缺失的数字
- 每日一题-搜索二维矩阵ps二维数组的查找
猜你喜欢
Sword finger offer 06 Print linked list from beginning to end
Talking about JVM (frequent interview)
Light a light with stm32
Corridor and bridge distribution (csp-s-2021-t1) popular problem solution
SAP method of modifying system table data
【实战技能】非技术背景经理的技术管理
[practical skills] technical management of managers with non-technical background
中职网络安全技能竞赛——广西区赛中间件渗透测试教程文章
【Jailhouse 文章】Performance measurements for hypervisors on embedded ARM processors
Sword finger offer 35 Replication of complex linked list
随机推荐
Sword finger offer 04 Search in two-dimensional array
ALU逻辑运算单元
Graduation project of game mall
Dichotomy, discretization, etc
6. Logistic model
Implement an iterative stack
kubeadm系列-00-overview
Personal developed penetration testing tool Satania v1.2 update
“磐云杯”中职网络安全技能大赛A模块新题
Control Unit 控制部件
One question per day 1447 Simplest fraction
剑指 Offer 06.从头到尾打印链表
Acwing 4300. Two operations
After setting up the database and website When you open the app for testing, it shows that the server is being maintained
注解与反射
Mysql database (I)
剑指 Offer 05. 替换空格
R语言【数据集的导入导出】
Daily question 2006 Number of pairs whose absolute value of difference is k
Convolution neural network -- convolution layer