首页 > 试题广场 >

矩阵最长递增路径

[编程题]矩阵最长递增路径
  • 热度指数:69426 时间限制:C/C++ 3秒,其他语言6秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
给定一个 n 行 m 列矩阵 matrix ,矩阵内所有数均为非负整数。 你需要在矩阵中找到一条最长路径,使这条路径上的元素是递增的。并输出这条最长路径的长度。
这个路径必须满足以下条件:

1. 对于每个单元格,你可以往上,下,左,右四个方向移动。 你不能在对角线方向上移动或移动到边界外。
2. 你不能走重复的单元格。即每个格子最多只能走一次。

数据范围:
进阶:空间复杂度 ,时间复杂度

例如:当输入为[[1,2,3],[4,5,6],[7,8,9]]时,对应的输出为5,
其中的一条最长递增路径如下图所示:

示例1

输入

[[1,2,3],[4,5,6],[7,8,9]]

输出

5

说明

1->2->3->6->9即可。当然这种递增路径不是唯一的。       
示例2

输入

[[1,2],[4,3]]

输出

4

说明

 1->2->3->4   

备注:
矩阵的长和宽均不大于1000,矩阵内每个数不大于1000
public class Solution {
    var res = 0
    func solve ( _ matrix: [[Int]]) -> Int {        
        for i in 0..<matrix.count {
            for j in 0..<matrix[i].count {
                var arr = [Int]() //寻找到的路径
                dfs(matrix, r: i, c: j, arr: &arr)
            }
        }
        return res
    }
    
    func dfs(_ matrix: [[Int]], r: Int, c: Int, arr: inout [Int]) {
        //判断界限
        if r < 0 || r >= matrix.count || c < 0 || c >= matrix[r].count {
            res = max(res, arr.count)
            return
        }
        //如果下一个节点小于最后的数字,则可以跳过
        if let lastNum = arr.last, matrix[r][c] <= lastNum {
            res = max(res, arr.count)
            return
        }
        arr.append(matrix[r][c])
        //开始递归寻找
        dfs(matrix, r: r, c: c - 1, arr: &arr) //上
        dfs(matrix, r: r, c: c + 1, arr: &arr) //下
        dfs(matrix, r: r - 1, c: c, arr: &arr) //左
        dfs(matrix, r: r + 1, c: c, arr: &arr) //右
        arr.removeLast()
    }
}

发表于 2026-01-28 16:19:00 回复(0)
func longestIncreasingPath(_ grid: [[Int]]) -> Int {
    guard grid.count > 0 else {
        return 0
    }
    var matrix: [[Int]] = grid
    var visitedMatrix: [[Bool]] = Array(repeating: Array(repeating: false, count: matrix[0].count), count: matrix.count)
    var result = 0
    for row in 0 ..< matrix.count {
        for col in 0 ..< matrix[0].count {
            if !visitedMatrix[row][col] {
                let lenOfPath = findIncreasingPath(&matrix, &visitedMatrix, row, col, 0)
                result = max(result, lenOfPath)
            }
        }
    }
    return result
}

// 递归查找递增的子串长度
func findIncreasingPath(_ matrix: inout [[Int]], _ visited: inout [[Bool]], _ row: Int, _ col: Int, _ curLen: Int) -> Int {
    guard row >= 0, row < matrix.count, col >= 0, col < matrix[0].count, !visited[row][col] else {
        return curLen
    }

    var lenOfPath = curLen + 1
    visited[row][col] = true // 标记该结点正在访问
    let curVal = matrix[row][col]

    // 依次向四个方向查找可以构成递增的字符串
    // 向上
    if row - 1 >= 0, matrix[row - 1][col] > curVal {
        let len = findIncreasingPath(&matrix, &visited, row - 1, col, curLen + 1)
        lenOfPath = max(len, lenOfPath)
    }

    // 向下
    if row + 1 < matrix.count, matrix[row + 1][col] > curVal {
        let len = findIncreasingPath(&matrix, &visited, row + 1, col, curLen + 1)
        lenOfPath = max(len, lenOfPath)
    }

    // 向左
    if col - 1 >= 0, matrix[row][col - 1] > curVal {
        let len = findIncreasingPath(&matrix, &visited, row, col - 1, curLen + 1)
        lenOfPath = max(len, lenOfPath)
    }

    // 向右
    if col + 1 < matrix[0].count, matrix[row][col + 1] > curVal {
        let len = findIncreasingPath(&matrix, &visited, row, col + 1, curLen + 1)
        lenOfPath = max(len, lenOfPath)
    }

    // 回溯——当前访问的节点为未访问
    visited[row][col] = false

    return lenOfPath
}

发表于 2023-08-14 12:22:14 回复(0)