1.DFS
#include <vector>
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
* 递增路径的最大长度
* @param matrix int整型vector<vector<>> 描述矩阵的每个数
* @return int整型
*/
void dfs(vector<vector<int>>& matrix,int &count,vector<vector<int>>& visited,int i,int j,int n,int m,int &max)
{
visited[i][j] = 1;
count++;
if(max < count)
max = count;
if(i-1>=0 && visited[i-1][j] == 0 && matrix[i-1][j] > matrix[i][j])
dfs(matrix, count, visited, i-1, j, n, m,max);
if(i+1<n && visited[i+1][j] == 0 && matrix[i+1][j] > matrix[i][j])
dfs(matrix, count, visited, i+1, j, n, m,max);
if(j-1>=0 && visited[i][j-1] == 0 && matrix[i][j-1] > matrix[i][j])
dfs(matrix, count, visited, i, j-1, n, m,max);
if(j+1<m && visited[i][j+1] == 0 && matrix[i][j+1] > matrix[i][j])
dfs(matrix, count, visited, i, j+1, n, m,max);
visited[i][j] = 0;
count--;
}
int solve(vector<vector<int> >& matrix) {
// write code here
int count = 0;
int n = matrix.size();
int m = matrix[0].size();
int max = 0;
vector<vector<int>> visited(n,vector<int>(m,0));
for(int i = 0;i<n;++i)
{
for(int j = 0;j<m;++j)
{
dfs(matrix, count, visited, i, j, n, m, max);
}
}
return max;
}
};
2.BFS
思路:
我们可以将矩阵看成是一个有向图,一个元素到另一个元素递增,代表有向图的箭头。这样我们可以根据有向图的出度入度找到最长的路径,且这个路径在矩阵中就是递增的。
具体做法:
- step 1:计算每个节点(单元格)所对应的出度(符合边界条件且递增),对于作为边界条件的单元格,它的值比所有的相邻单元格的值都要大,因此作为边界条件的单元格的出度都为0。利用一个二维矩阵记录每个单元格的出度
- step 2:利用拓扑排序的思想,从所有出度为0的单元格开始进行广度优先搜索。
- step 3:借助队列来广度优先搜索,队列中每次加入出度为0的点,即路径最远点,每次从A点到B点,便将A点出度减一。
- step 4:每次搜索都会遍历当前层的所有单元格,更新其余单元格的出度,并将出度变为0的单元格加入下一层搜索。
- step 5:当搜索结束时,搜索的总层数即为矩阵中的最长递增路径的长度,因为bfs的层数就是路径增长的层数。
#include <queue>
#include <vector>
class Solution {
public:
int solve(vector<vector<int> >& matrix) {
// write code here
int n = matrix.size();
int m = matrix[0].size();
int dirs[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};//记录四个方向
vector<vector<int>> outdegrees(n,vector<int>(m,0));//记录每个单元的出度
for(int i = 0;i<n;i++)
{
for(int j = 0;j<m;j++)
{
for(int k = 0;k<4;k++)
{
int nexti = i + dirs[k][0];
int nextj = j + dirs[k][1];
if(nexti >= 0 && nexti < n && nextj >= 0 && nextj < m && matrix[nexti][nextj] > matrix[i][j])
{
outdegrees[i][j]++;//符合条件,记录出度
}
}
}
}
queue<pair<int,int>> q;
for(int i = 0;i<n;i++)
{
for(int j = 0;j<m;j++)
{
//出度为0的数就是周围的数都比它的小的那些数
if(outdegrees[i][j] == 0)
q.push({i,j});//找到出度为0的入队列
}
}
int res = 0;
//逆向思维:从路径最远点出发,找到路径的头,也就是出度为0的点,途中记录该路径的长度
while(!q.empty())
{
res++;
int size = q.size();
for(int x = 0;x < size ; x++)
{
pair<int,int> temp = q.front();
q.pop();
int i = temp.first;
int j = temp.second;
//四个方向
for(int k = 0;k<4;++k)
{
int nexti = i + dirs[k][0];
int nextj = j + dirs[k][1];
//逆向搜索,所以下一步是小于
if(nexti >= 0 && nexti < n && nextj >= 0 && nextj < m && matrix[nexti][nextj] < matrix[i][j])
{
//符合条件,出度递减
outdegrees[nexti][nextj]--;
if(outdegrees[nexti][nextj] == 0)
q.push({nexti,nextj});
}
}
}
}
return res;
}
};



京公网安备 11010502036488号