LeetCode 329. Longest Increasing Path in a Matrix

一、题目描述

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:

Input: nums =
[
 [9,9,4],
 [6,6,8],
 [2,1,1]
]
Output: 4
Explanation: The longest increasing path is [1, 2, 6, 9].

Example 2:

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

 


 

二、题目分析

  根据题意,我们需要在给定的矩阵中找出一个最长的递增序列,返回其长度。
  在这里我们可以将给定的矩阵近似看成有向图,当且仅当图的每个顶点(数字)的周围(上下左右四个方向)的顶点的数字大于该顶点时,才有从该顶点指向另一顶点的边。

  • e.g. 题目的Example2 中给出的矩阵形成的图如下:
    graph

将矩阵看作图后,我们就可以将问题转换成求图的最长路径的长度,自然我们使用DFS来找这样的一条路径,即以图的每一个顶点作为DFS的起点,在搜索时使用二维数组记录从每个顶点出发的最长路径长度(若该点出度为0,则其最长路径长度为1)。这里将二维数组初始化为0,就可以通过判断数组某个位置是否等于0作为对应的顶点是否访问过的依据,减少搜索次数。我们在遍历图时,记录下最大值,在最后返回。

 


 

三、具体实现

通过上面分析,可知算法复杂度为 O ( n 2 ) O(n^2) O(n2)。实现如下:

class Solution {
    public:
        int longestIncreasingPath( vector<vector<int>> &matrix ) {
            
            width = matrix.size();
            if ( width == 0 )
                return 0;

            len = matrix.at( 0 ).size();

            int **res = new int*[width];
            for ( int i = 0; i < width; ++i )
                res[i] = new int[len]();

            int pathLen = 0;
            for ( int i = 0; i < width; ++i ) {
                for ( int j = 0; j < len; ++j ) {
                    if ( res[i][j] == 0 )
                        pathLen = max( pathLen, DFS( matrix, i, j, res ) );
                }
            }

            for ( int i = 0; i < width; ++i )
                delete [] res[i];
            delete [] res;

            return pathLen;

        }

    private:

        const pair<int, int> direction[4]
            = { make_pair( -1, 0 ), make_pair( 1, 0 ), make_pair( 0, -1 ), make_pair( 0, 1 ) };

        int width;
        int len;

        int DFS( vector<vector<int>> &matrix, int _x, int _y, int **res ) {

            bool maxima = true;                 // to check whether matrix[_x][_y] is maxima
            for ( int i = 0; i < 4; ++i ) {     // 4 directions

                int x = _x + direction[i].first, y = _y + direction[i].second;
                if ( x < 0 || y < 0 || x >= width || y >= len || matrix[x][y] <= matrix[_x][_y] )
                    continue;

                maxima = false;

                if ( res[x][y] != 0 )
                    res[_x][_y] = max( 1 + res[x][y], res[_x][_y] );
                else
                    res[_x][_y] = max( 1 + DFS( matrix, x, y, res ), res[_x][_y] );

            }

            if ( maxima )
                res[_x][_y] = 1;

            return res[_x][_y];

        }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值