每日算法系列【LeetCode 329】矩阵中的最长递增路径

简介: 给定一个整数矩阵,找出最长递增路径的长度。对于每个单元格,你可以往上,下,左,右四个方向移动。你不能在对角线方向上移动或移动到边界外(即不允许环绕)。

题目描述


给定一个整数矩阵,找出最长递增路径的长度。

对于每个单元格,你可以往上,下,左,右四个方向移动。你不能在对角线方向上移动或移动到边界外(即不允许环绕)。

示例1

输入:
nums = [  [9,9,4],  [6,6,8],  [2,1,1]]
输出:
4
解释:
最长递增路径为 [1, 2, 6, 9]。

示例2

输入:
nums = [  [3,4,5],  [3,2,6],  [2,2,1]]
输出:
4
解释:
最长递增路径是 [3, 4, 5, 6]。注意不允许在对角线方向上移动。

题解


DFS+记忆化搜索


image.png

拓扑排序


image.png

代码


DFS+记忆化搜索(c++)

classSolution {
public:    
intdx[4] = {0, 0, 1, -1}; 
intdy[4] = {1, -1, 0, 0};
intlongestIncreasingPath(vector<vector<int>>&matrix) {    
intn=matrix.size();  
if (!n) return0;    
intm=matrix[0].size();  
vector<vector<int>>dp(n, vector<int>(m, 0)); 
intres=1;   
for (inti=0; i<n; ++i) {     
for (intj=0; j<m; ++j) { 
dp[i][j] =dfs(matrix, i, j, dp); 
res=max(res, dp[i][j]);  
            }     
        }       
returnres; 
    }
intdfs(vector<vector<int>>&matrix, intx, inty, 
vector<vector<int>>&dp) {  
if (dp[x][y] >0) returndp[x][y];  
intn=matrix.size(), m=matrix[0].size(); 
dp[x][y] =1;   
for (inti=0; i<4; ++i) {  
intnx=x+dx[i], ny=y+dy[i];  
if (inside(nx, ny, n, m) &&matrix[nx][ny] <matrix[x]
                [y]) {      
dp[x][y] =max(dp[x][y], dfs(matrix, nx, ny, dp)+1);
            }       
        }    
returndp[x][y];  
    }
boolinside(intx, inty, intn, intm) {   
return0<=x&&x<n&&0<=y&&y<m; 
    }
};

拓扑排序(c++)

classSolution {
public:  
intdx[4] = {0, 0, 1, -1};    intdy[4] = {1, -1, 0, 0};
intlongestIncreasingPath(vector<vector<int>>&matrix) {  
intn=matrix.size();   
if (!n) return0;   
intm=matrix[0].size();   
vector<vector<int>>dp(n, vector<int>(m, 0));    
vector<vector<int>>degree(n, vector<int>(m, 0));    
queue<pair<int, int>>Q;   
for (inti=0; i<n; ++i) {   
for (intj=0; j<m; ++j) {   
for (intk=0; k<4; ++k) {      
intnx=i+dx[k], ny=j+dy[k];   
if (inside(nx, ny, n, m) &&matrix[nx][ny] <matrix[i][j]) {         
degree[i][j]++;        
                    }        
                }   
if (!degree[i][j]) { 
Q.push({i, j});    
dp[i][j] =1;    
                }        
            }      
        }      
intres=1;   
while (!Q.empty()) {  
intx=Q.front().first, y=Q.front().second;   
Q.pop();     
res=max(res, dp[x][y]);     
for (inti=0; i<4; ++i) {     
intnx=x+dx[i], ny=y+dy[i];      
if (inside(nx, ny, n, m) &&matrix[nx][ny] >matrix[x][y]) {      
if (!(--degree[nx][ny])) {    
Q.push({nx, ny});   
                    }     
dp[nx][ny] =max(dp[nx][ny], dp[x][y]+1);                }       
            }    
        }     
returnres; 
    }
boolinside(intx, inty, intn, intm) {  
return0<=x&&x<n&&0<=y&&y<m;   
    }
};

image.png

作者简介:godweiyang知乎同名华东师范大学计算机系硕士在读,方向自然语言处理与深度学习喜欢与人分享技术与知识,期待与你的进一步交流~


相关文章
|
3月前
【LeetCode 35】112.路径总和
【LeetCode 35】112.路径总和
33 0
|
3月前
【LeetCode 36】113.路径总和II
【LeetCode 36】113.路径总和II
35 0
|
5月前
|
存储 算法 NoSQL
LeetCode第73题矩阵置零
文章介绍了LeetCode第73题"矩阵置零"的解法,通过使用矩阵的第一行和第一列作为标记来记录哪些行或列需要置零,从而在不增加额外空间的情况下解决问题。
LeetCode第73题矩阵置零
|
3月前
【LeetCode 34】257.二叉树的所有路径
【LeetCode 34】257.二叉树的所有路径
28 0
|
3月前
|
算法 C++
Leetcode第59题(螺旋矩阵2)
这篇文章介绍了解决LeetCode第59题“螺旋矩阵II”的算法,通过C++编程实现按顺时针顺序填充一个n x n的正方形矩阵。
22 0
|
5月前
|
存储 算法 Linux
LeetCode第71题简化路径
文章讲述了LeetCode第71题"简化路径"的解题方法,利用栈的数据结构特性来处理路径中的"."和"..",实现路径的简化。
LeetCode第71题简化路径
|
5月前
|
算法
LeetCode第64题最小路径和
LeetCode第64题"最小路径和"的解题方法,运用动态规划思想,通过构建一个dp数组来记录到达每个点的最小路径和,从而高效求解。
LeetCode第64题最小路径和
|
5月前
|
算法 Java
LeetCode经典算法题:矩阵中省份数量经典题目+三角形最大周长java多种解法详解
LeetCode经典算法题:矩阵中省份数量经典题目+三角形最大周长java多种解法详解
63 6
|
5月前
|
算法 Python
【Leetcode刷题Python】73. 矩阵置零
本文介绍了LeetCode第73题的解法,题目要求在给定矩阵中将所有值为0的元素所在的行和列全部置为0,并提供了一种原地算法的Python实现。
43 0
【Leetcode刷题Python】73. 矩阵置零
|
5月前
|
算法 Java
LeetCode初级算法题:子数组最大平均数+二叉树的最小深度+最长连续递增序列+柠檬水找零
LeetCode初级算法题:子数组最大平均数+二叉树的最小深度+最长连续递增序列+柠檬水找零
49 0