很典型的搜索题目,一共有两种方法可以做。即深搜和广搜。
目录
1.深搜
这里的深搜有点动态规划的味道。
我们设置一个dp数组代表以当前节点为起点能够走的最长路径。这有个好处就是之后我们遍历到这个点的时候不必再去搜索一遍了。
首先要想明白一件事,那就是,如果有一条最长路径,那么这条路径上的所有点的最长路径都是这一条。否则原来的最长二字不成立。基于此,我们一次搜索就可以求出该路径上所有点的最长路径值。
于是对于每一个遍历到的坐标,我们进行如下操作:
如果dp[x][y]不为0,说明之前已经生成了其最长路径,则直接返回。
否则说明dp[x][y]为0,说明还未求出以该节点为起点的最长路径。此时我们初始化dp为,假定最长路径只包含当前这个节点。
之后:
对四个方位的节点进行处理,当某个方位的点合法并且这个点的数值大于当前节点的数值,我们可以继续递归,然后取dp[i][j]=max(dp[i][j],dfs+1),这里的dfs即是我们的递归函数
返回dp[x][y]
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
* 递增路径的最大长度
* @param matrix int整型vector<vector<>> 描述矩阵的每个数
* @return int整型
*/
const int dir_X[4]={0,0,-1,1};
const int dir_Y[4]={-1,1,0,0};
bool isValid(vector<vector<int>> &matrix,int x,int y){
return x>=0&&x<matrix.size()&&y>=0&&y<matrix[0].size();
}
int dfs(vector<vector<int> >& matrix, vector<vector<int>> &dp,int x,int y){
if(dp[x][y]!=0){
return dp[x][y];
}
dp[x][y]++;
for(int i=0;i<4;++i){
int dx=x+dir_X[i];
int dy=y+dir_Y[i];
if(isValid(matrix, dx, dy) && matrix[x][y]<matrix[dx][dy]){
dp[x][y]=max(dp[x][y],dfs(matrix,dp,dx,dy)+1);
}
}
return dp[x][y];
}
int solve(vector<vector<int> >& matrix) {
int res=0;
vector<vector<int>> dp(matrix.size(),vector<int>(matrix[0].size(),0));
for(int i=0;i<matrix.size();++i){
for(int j=0;j<matrix[0].size();++j){
res=max(res,dfs(matrix,dp,i,j));
}
}
return res;
}
};
2.广搜
除了深搜外,我们还能用广搜来实现反向寻找路径。
我们用一点数据结构的知识,记录每个节点的出度,然后出度为0的点就是我们开始广搜的节点。
思路如下所示:
首先求出所有点的出度,然后将出度为0的点先压入队列中。
接下来进行BFS,当队列不空时进行如下操作:
1.求出当前层的size
2.对size内的队列前部坐标进行如下操作:
求得合法的,并且坐标值是小于当前节点的坐标(这里是反过来的,因为我们是从终点向起点搜索),然后将对应的方位的坐标节点的出度减1,当此该节点的出度为0时,说明从该节点能到达路径都已遍历过,于是将该节点压入队列。
最长的路径一定会让队列不为空的状态持续到最后,代码如下所示:
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
* 递增路径的最大长度
* @param matrix int整型vector<vector<>> 描述矩阵的每个数
* @return int整型
*/
const int dir_X[4]={0,0,-1,1};
const int dir_Y[4]={-1,1,0,0};
bool isValid(vector<vector<int>> &matrix,int x,int y){
return x>=0&&x<matrix.size()&&y>=0&&y<matrix[0].size();
}
int solve(vector<vector<int> >& matrix) {
int row=matrix.size(),col=matrix[0].size();
vector<vector<int>> outdegree(row,vector<int>(col));
for(int i=0;i<row;++i){
for(int j=0;j<col;++j){
for(int k=0;k<4;++k){
int dx=i+dir_X[k];
int dy=j+dir_Y[k];
if(isValid(matrix, dx, dy) && matrix[i][j]<matrix[dx][dy]){
outdegree[i][j]++;
}
}
}
}
queue<pair<int, int>>q;
for(int i=0;i<row;++i){
for(int j=0;j<col;++j){
if(!outdegree[i][j]){
q.push({i,j});
}
}
}
int res=0;
while(!q.empty()){
res++;
int size=q.size();
for(int x=0;x<size;++x){
pair<int, int> tmp=q.front();
q.pop();
int i=tmp.first;
int j=tmp.second;
for(int k=0;k<4;++k){
int dx=i+dir_X[k];
int dy=j+dir_Y[k];
if(isValid(matrix, dx, dy) && matrix[i][j]>matrix[dx][dy]){
outdegree[dx][dy]--;
if(outdegree[dx][dy]==0){
q.push({dx,dy});
}
}
}
}
}
return res;
}
};