329. 矩阵中的最长递增路径C语言

给定一个 m x n 整数矩阵 matrix ,找出其中 最长递增路径 的长度。

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-increasing-path-in-a-matrix
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

方法一:
深度优先搜索
这个方法不优化的思路是(虽然优化和不优化之后结果都是135/138)
和先序遍历差不多9(套模板)
但是不同的是(由于数组越界的问题):
情况一:选择加递归上出口
那么就要把数组扩大一圈,防止越界
情况二:不加递归上出口
不扩大数组,只是在if限制一下边界条件就好了
优化之后(看了官方题解发现的):
在原先的基础上加一个记忆数组,然后以每一个元素为递增序列的初始元素,(要注意的是一定要在经过一个数之后再去赋值);如果经历到这个元素并且不为0,他之后的最大序列就自然的加到后面了,虽然实现了这个但还是135/138,wofule
代码
这个是没设递归上出口

int u1,trap;
int n1,n2;
 
struct point
{
    int x, y;
};
void travel(int **matrix ,int i,int j,int u,int memo[][n2+2])
{
       //printf("%d",u);
printf("%d %d\n",matrix[i][j],u);
      
      if(memo[i][j]!=0 )
      {
          u=u+memo[i][j];
        if(u>u1)u1=u;
        if(u>trap)trap=u;
          return;
      }
      u++;
     if(i>=0&&i<n1&&j<n2&&j>0&&matrix[i][j-1]>matrix[i][j])
      { travel(matrix,i,j-1,u,memo);}
      if(i>=0&&i<n1&&j>=0&&j<(n2-1)&&matrix[i][j+1]>matrix[i][j])
      travel(matrix,i,j+1,u,memo);
      if(i>=0&&i<(n1-1)&&j>=0&&j<n2&&matrix[i][j]<matrix[i+1][j])
      travel(matrix,i+1,j,u,memo);
     if(i>0&&i<n1&&j>=0&&j<n2&&matrix[i-1][j]>matrix[i][j])
      travel(matrix,i-1,j,u,memo);
      if(u>trap)
      {trap=u;}
       if(u1>u)
       u1=u;
     
}
int longestIncreasingPath(int** matrix, int matrixSize, int* matrixColSize)//长方形扩充错误,s++错误
{
          n1=matrixSize,n2=*matrixColSize;
          trap=0;
          int u;
         
          int a[n1+2][n2+2],s=0;
          int memo[n1+2][n2+2];

          int min=matrix[0][0],max=matrix[0][0];
          
          for(int i=0;i<(n1+2);i++)
          {
              for(int j=0;j<(n2+2);j++)
              {
                  memo[i][j]=0;
              }
          }
         
         
         for(int i=0;i<n1;i++)
         {
             for(int j=0;j<n2;j++)
             {
                 u1=0;
                 travel(matrix,i,j,0,memo);
                  memo[i][j]=u1;
             }
         }

          return  trap;
}

方法二:
层序遍历
用一个结构体数组,存储下标,倒也不失为一个好方法ojbk,想到层序遍历的时候没想到这以为只有链表带指针的才能实现,其实只要保存好数组下标就可以啦。然后其他的就是层序遍历了,他的一圈数字是一层(可以进入队列的最多只有4个)这个想法其实挺简单的,就是套模板了

int n1,n2;
int ceng,u;
struct point
{
    int x, y;
};
void cengxu(int **matrix ,int a,int b)
{
    struct point cell[20000];
        int rear,s,i;
        int q[20000]={0};
        i=0;rear=0,s=1;
        q[0]=matrix[a][b];
        cell[0].x=a;cell[0].y=b;
        while(rear<s)
        {
            rear=s;
            while(i<rear)
            {
               int  a=cell[i].x,b=cell[i].y;
                if(s>0&&s<20000&&a>=0&&a<(n1-1)&&b>=0&&b<n2&&matrix[a][b]<matrix[a+1][b])
                {
                    q[s++]=matrix[a+1][b];
                    cell[s-1].x=a+1,cell[s-1].y=b;
                    printf("YES");
                }
                if(s>0&&s<20000&&a>=1&&a<n1&&b>=0&&b<n2&&matrix[a][b]<matrix[a-1][b])
                {
                    q[s++]=matrix[a-1][b];
                    cell[s-1].x=a-1,cell[s-1].y=b;
                       printf("YES1");
                }
                 if(s>0&&s<20000&&a>=0&&a<n1&&b>=0&&b<(n2-1)&&matrix[a][b]<matrix[a][b+1])
                {
                    q[s++]=matrix[a][b+1];
                    cell[s-1].x=a,cell[s-1].y=b+1;
                       printf("YES2");
                }
                 if(s>0&&s<20000&&a>=0&&a<n1&&b>0&&b<n2&&matrix[a][b]<matrix[a][b-1])
                {
                    q[s++]=matrix[a][b-1];
                    cell[s-1].x=a,cell[s-1].y=b-1;   printf("YES3");
                }
                i++;
            }
            ceng++;printf("%d ",ceng);
        }
} 

int longestIncreasingPath(int** matrix, int matrixSize, int* matrixColSize)
{
        
       n1=matrixSize,n2=*matrixColSize;
       u=0,ceng=0;
       for(int i=0;i<matrixSize;i++)
       {
           for(int j=0;j<*matrixColSize;j++)
           {
               u=ceng;
               ceng=0;
               printf("%d ",matrix[i][j]);
               cengxu(matrix,i,j);
               printf("\n");
               if(ceng<u)
               ceng=u;
             //printf("YES");
               
           }
       }
       return ceng;

}

有一些小问题需要注意
1.关于S++问题
在使用一次S++之后如果还想用S值一定要写S-1;
2.矩形扩充是加两个边长;
3.关于全局变量与递归变量(函数参数)
{
在函数中如果有函数参数与全局变量同名,全局变量值应该会被忽略,在本题中最一开始的时候发现,递归变量设置成全局变量了,因为不想求联通部分面积,所以把值放在了函数参数里,然而结果是一样的。。所以得到了结论嘿嘿
还有就是在递归的过程中不要在本函数栈中改变函数参量的值或者说改的话一定要慎重,看好函数参数应该是那个函数栈里的,然后再改,也就是不要轻易赋值或加加减减
还有就是在递归终点返回的值在上下出口设置就可以了,耶斯
}
4.反复利用的值可能涉及到初始化的问题
希望有大佬能教一下怎么优化了

以上仅为个人观点,如有不当请指正

你可能感兴趣的:(329. 矩阵中的最长递增路径C语言)