首页 > 代码库 > [LeetCode]Longest Increasing Path in a Matrix

[LeetCode]Longest Increasing Path in a Matrix

题目: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:

nums = [
  [9,9,4],
  [6,6,8],
  [2,1,1]
]

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

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.

题目:

给定一个二维数组,找到一条连通路径,使得该路径上的数字依次递增,路径智能上下左右相连。

思路:

首先考虑如何找一条最长递增路径,可以使用递归,因为不找到最后不知道上下左右四个方向哪个对应着最优解,所以循环的话需要回溯,使用递归能更好的实现它。

然后,很容易发现找到一条路径后,上面的所有点都不用再找了,因为以它为起点的最长递增路径已经找到了,如何避免重复查找呢?

这样考虑就发现需要一个二维数组记录以给定二位数组中每个位置为起点的最长递增路径的长度。而每到下一个位置的记录值不是初始值,则不用在递归下去,这样就能重复利用已找到的路径。

于是,只需要比较每次的最大值就可以了。

int LeetCode::longestIncreasingPath(vector<vector<int>>& matrix){
    if (matrix.size() < 1 || matrix[0].size() < 1)return 0;
    vector<vector<int>> result(matrix.size(), vector<int>(matrix[0].size(), 1));
    int m = 1;
    for (size_t i = 0; i < matrix.size(); ++i){
        for (size_t j = 0; j < matrix[i].size(); ++j){
            if (result[i][j] == 1)longestIncreasingPath(matrix, result, i, j);
            m = max(m, result[i][j]);
        }
    }
    return m;
}

/**lengths矩阵保存i,j位置的最大递增长度**/
void LeetCode::longestIncreasingPath(vector<vector<int>>& matrix, vector<vector<int>>& lengths, int i, int j){
    int m = 1;//最长路径的初值,1表示其本身
    if (i > 0 && matrix[i][j] < matrix[i - 1][j]){//上边的值较大
        if (lengths[i - 1][j] == 1)longestIncreasingPath(matrix, lengths, i - 1, j);//如果没求过,则递归求该位置的值
        m = max(m, lengths[i - 1][j] + 1);
    }
    if (j + 1 < matrix[0].size() && matrix[i][j] < matrix[i][j + 1]){//右边的值较大
        if (lengths[i][j + 1] == 1)longestIncreasingPath(matrix, lengths, i, j + 1);//如果没求过,则递归求该位置的值
        m = max(m, lengths[i][j + 1] + 1);
    }
    if (i + 1 < matrix.size() && matrix[i][j] < matrix[i + 1][j]){//下边的值较大
        if (lengths[i + 1][j] == 1)longestIncreasingPath(matrix, lengths, i + 1, j);//如果没求过,则递归求该位置的值
        m = max(m, lengths[i + 1][j] + 1);
    }
    if (j > 0 && matrix[i][j] < matrix[i][j - 1]){//左边的值较大
        if (lengths[i][j - 1] == 1)longestIncreasingPath(matrix, lengths, i, j - 1);//如果没求过,则递归求该位置的值
        m = max(m, lengths[i][j - 1] + 1);
    }
    lengths[i][j] = m;
}

上面代码中

if (result[i][j] == 1)longestIncreasingPath(matrix, result, i, j);

这一句是关键,它能大幅度提高效率。它使得程序不会重复找已找过的路径。

整个思路是深度优先搜索的思路。

[LeetCode]Longest Increasing Path in a Matrix