一、题目简述
给定一个整数矩阵,找到最长递增路径
对于每个元素,可以在四个方向上移动:上下左右,不可以沿对角线方向移动。
例如:
nums=⎡⎣⎢962961481⎤⎦⎥
返回:4,其中最长路径为 [1,2,6,9] .
二、编程思路
对于该题可以使用带记忆的深度优先搜索实现。对于坐标为 [x,y] 的元素 ele ,以 ele 作为起始点的最长路径长度为其上下左右元素中值大于 ele 的最长路径加1,即为
max_path(x,y)=max{max_path(x−1,y),max_path(x+1,y),max_path(x,y−1),max_path(x,y+1)}+1
若元素 ele 四周没有大于它的元素,则其最长路径为1。
在每次计算最长路径 max_path 之后,都将其值记录矩阵 pth_len 中,减少计算量。
三、程序设计
class Solution {
public:
int findPath(vector<vector<int> >& matrix,vector<vector<int> >& pth_len,int x,int y){
if(pth_len[x][y]) return pth_len[x][y];
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
int rows,cols;
rows=matrix.size();
cols=matrix[0].size();
bool is_next=false;// is there any point to be next point
int cur_pth_len=0;
int cur_max_pth=0;
for(int i=0;i<4;i++){
int nx=x+dx[i];
int ny=y+dy[i];
if(nx>=0 && nx<rows && ny>=0 && ny<cols
&& (matrix[nx][ny]>matrix[x][y])){
cur_pth_len=findPath(matrix,pth_len,nx,ny);
if(cur_pth_len>cur_max_pth){
cur_max_pth=cur_pth_len;
}
is_next=true;
}
}
if(is_next){
pth_len[x][y]=cur_max_pth+1;
return pth_len[x][y];
}else{
pth_len[x][y]=1;
return 1;
}
}
int longestIncreasingPath(vector<vector<int> >& matrix) {
vector<vector<int> > pth_len;
for(int i=0;i<matrix.size();i++){
vector<int> v;
for(int j=0;j<matrix[0].size();j++){
v.push_back(0);
}
pth_len.push_back(v);
}
// cout<<"construct path len"<<endl;
int max_pth_len=0;
for(int i=0;i<matrix.size();i++){
for(int j=0;j<matrix[0].size();j++){
// cout<<i<<" "<<j<<" ";
int tmp=findPath(matrix,pth_len,i,j);
if(tmp>max_pth_len)
max_pth_len=tmp;
// cout<<tmp<<endl;
}
}
// cout<<"pth_len"<<endl;
// for(int i=0;i<matrix.size();i++){
// for(int j=0;j<matrix[0].size();j++){
// cout<<pth_len[i][j]<<" ";
// }
// cout<<endl;
// }
return max_pth_len;
}
};
四、实验心得
使用有记忆的搜索可以减少计算量,降低算法复杂度。