思路:1:记忆化搜索:由于路径可以保证前一个节点一定小于后一个节点,故不可能产生重叠情况,故采用记忆化搜索即可。
2.拓扑排序,把该图看为有向图,相邻的两个节点中,其较小的顶点有一条边指向较大顶点,故可以采用拓扑排序来做。
class Solution {//记忆化搜索
public:
int dx[4]={1,-1,0,0};
int dy[4]={0,0,1,-1};
int Dfs(vector<vector<int>>& matrix,vector<vector<int>>& d,int x,int y,int n,int m){
if(d[x][y]!=0) return d[x][y];
int k=0;
for(int i=0;i<4;i++){
int ix=x+dx[i];
int iy=y+dy[i];
if(ix>=0&&ix<n&&iy>=0&&iy<m&&matrix[ix][iy]>matrix[x][y])
{
k=max(k,Dfs(matrix,d,ix,iy,n,m));
}
}
return d[x][y]=k+1;
}
int longestIncreasingPath(vector<vector<int>>& matrix) {
int n=matrix.size();
if(n==0) return 0;
int m=matrix[0].size();
vector<vector<int>> d(n,vector<int>(m,0));
int ans=0;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
int val=Dfs(matrix,d,i,j,n,m);
ans=max(ans,val);
}
}
return ans;
}
};
class Solution {//拓扑排序
public:
struct Node{
int x;
int y;
int val;
Node(int a,int b,int c){
x=a;
y=b;
val=c;
}
};
int dx[4]={1,-1,0,0};
int dy[4]={0,0,1,-1};
int longestIncreasingPath(vector<vector<int>>& matrix) {
int n=matrix.size();
if(n==0) return 0;
int m=matrix[0].size();
vector<vector<int>> d(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 ix=i+dx[k];
int iy=j+dy[k];
if(ix>=0&&ix<n&&iy>=0&&iy<m&&matrix[ix][iy]>matrix[i][j]){
++d[ix][iy];
}
}
}
}
int ans=0;
vector<vector<bool>> vis(n,vector<bool>(m,0));
queue<Node> p;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(d[i][j]==0){
vis[i][j]=1;
p.push(Node(i,j,1));
}
}
}
while(p.size()){
Node temp=p.front();
p.pop();
ans=max(ans,temp.val);
int x=temp.x,y=temp.y;
for(int i=0;i<4;i++){
int ix=x+dx[i];
int iy=y+dy[i];
if(ix>=0&&ix<n&&iy>=0&&iy<m&&!vis[ix][iy]&&matrix[ix][iy]>matrix[x][y])
{
d[ix][iy]--;
if(d[ix][iy]==0){
vis[ix][iy]=1;
p.push(Node(ix,iy,temp.val+1));
}
}
}
}
return ans;
}
};