LeetCode #329 - Longest Increasing Path in a Matrix - Hard

本文介绍了一种寻找矩阵中最长递增路径的算法。通过将问题转化为图中的最长路径问题,利用记忆化搜索减少重复计算,并采用深度优先搜索确定每个节点的最长递增路径长度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Problem

Given an integer matrix, find the length of the longest increasing path.

From each cell, you can either move to four directions: left, right, up or down. 
You may NOT move diagonally or move outside of the boundary (i.e. wrap-around is not allowed).

Example

1. Example 1:

nums = [
  [9,9,4],
  [6,6,8],
  [2,1,1]
]
Return 4
The longest increasing path is [1, 2, 6, 9].


2. Example 2:

nums = [
  [3,4,5],
  [3,2,6],
  [2,2,1]
]
Return 4
The longest increasing path is [3, 4, 5, 6]. Moving diagonally is not allowed.

Algorithm

整理一下题意:给定一个矩阵,要求在所有矩阵元素中找一条递增路径,要求返回最长递增路径的长度。

可以把邻接矩阵视为图,相邻两个节点有一条边相连,边的方向是由较小元素指向较大元素。于是问题可以转化为求图中的一条最长路径。

设各节点值dist[i][j]表示由该节点出发所得的最长递增路径长度,初始化均为0。遍历每个节点,分别以每个节点为起点,求其最长递增路径的长度。设置一个变量lip与各节点的值比较,得到的最大值即为题目所求。
对每个节点求最长递增路径长度的方法是以该节点为起点向四个方向(上下左右)分别进行DFS,最终得到的值与节点原来的值比较,取较大者保留。

需要注意的点:

  • 在dfs函数中,设置dx和dy数组表示方向移动情况。例如,dx[4]={0,0,1,-1}分别表示向上、向下、向左、向右的x变化情况;dy数组同理。

  • 若遍历到某节点[i][j]时,若dist[i][j]不为0,表示该节点已访问过,且dist[i][j]已经是该节点的最长递增路径长度了,所以可以直接使用。这种方法称为记忆化搜索。

  • 最后返回++dist[i][j],表示多走了一步,长度加一。

  • 设置m和n的目的是为了判断某次走步是否越界。因为矩阵长度应该是保持不变的,所以dfs函数参数中设置为const int

  • dfs函数参数传入matrix时,使用了&,表示引用传递。若去掉&,使用参数传递方法,提交会出现Time limit exceeded,超时。这是因为引用传递减少了matrix在函数中拷贝的过程,减少的时间使用

代码如下。

class Solution {
public:
    int longestIncreasingPath(vector<vector<int>>& matrix) {
        if(matrix.size()==0) return 0;
        int m=matrix.size();
        int n=matrix[0].size();
        vector<vector<int>> dist(m,vector<int>(n,0));
        int lip=0;
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
               lip=max(lip,dfs(m,n,i,j,matrix,dist));
            }
        }
        return lip;
    }
    int dfs(const int&m,const int&n,int x,int y, vector<vector<int>>& matrix, vector<vector<int>>&dist){

        if(dist[x][y]!=0) return dist[x][y];
        int mx,ny;
        for(int i=0;i<4;i++){
            mx=x+dx[i];
            ny=y+dy[i];
            if(mx>=0&&mx<m&&ny>=0&&ny<n&&matrix[mx][ny]>matrix[x][y]){
                dist[x][y]=max(dist[x][y],dfs(m,n,mx,ny,matrix,dist));
            }
        }
        return ++dist[x][y];
    }
private:
    int dx[4]={0,0,1,-1};
    int dy[4]={1,-1,0,0};
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值