📜  数组边界元素的最长递增序列(1)

📅  最后修改于: 2023-12-03 15:40:04.232000             🧑  作者: Mango

数组边界元素的最长递增序列

简介

数组边界元素的最长递增序列是指在一个二维矩阵中,以矩阵的边缘元素作为开头,沿着矩阵的边缘元素只走上、下、右、左四个方向,能够构成的最长递增序列。

例如下图中的矩阵:

1 2 3 4
9 8 7 6
10 11 12 13

以边缘元素1、2、3、4作为开头,可以分别得到长度为4、3、2、1的递增序列,所以该矩阵的边缘元素的最长递增序列的长度为4。

解法

该问题可以使用动态规划来解决。通过设计状态,以及状态转移方程,可以得到最优解。

状态设计

我们定义一个二维的状态数组 $dp[i][j]$,表示从二维矩阵中的位置 $(i,j)$ 出发,以当前位置为结尾能够得到的最长递增序列的长度。

状态转移方程

对于边缘元素而言,其初始值都为1,因为以它本身作为结尾的最长递增序列只有它一个元素。

接下来从边缘元素的四个方向进行扩展,每次将当前位置的值与相邻位置的值进行比较,若当前位置的值大于相邻位置的值,则以当前位置作为结尾的最长递增序列长度无法继续向下拓展,因此 $dp[i][j]$ 的值不变;若当前位置的值小于等于相邻位置的值,则可以将相邻位置的最长递增序列长度加1作为以当前位置作为结尾的最长递增序列长度:

$$dp[i][j] = \max(dp[i][j], dp[i-1][j]+1) \quad (i \geq 1)$$

$$dp[i][j] = \max(dp[i][j], dp[i][j-1]+1) \quad (j \geq 1)$$

$$dp[i][j] = \max(dp[i][j], dp[i+1][j]+1) \quad (i \leq n)$$

$$dp[i][j] = \max(dp[i][j], dp[i][j+1]+1) \quad (j \leq m)$$

其中,$n$ 和 $m$ 分别表示矩阵的行数和列数。

最终,边缘元素的最长递增序列长度即为 $dp[i][j]$ 数组中的最大值。

代码实现

以下为算法实现的python代码:

def findLIS(matrix):
    n, m = len(matrix), len(matrix[0])
    dp = [[1] * m for _ in range(n)]

    for i in range(n):
        for j in range(m):
            if i == 0 or j == 0 or i == n-1 or j == m-1:
                continue
            if matrix[i][j] > matrix[i-1][j]:
                dp[i][j] = max(dp[i][j], dp[i-1][j]+1)
            if matrix[i][j] > matrix[i][j-1]:
                dp[i][j] = max(dp[i][j], dp[i][j-1]+1)
            if matrix[i][j] > matrix[i+1][j]:
                dp[i][j] = max(dp[i][j], dp[i+1][j]+1)
            if matrix[i][j] > matrix[i][j+1]:
                dp[i][j] = max(dp[i][j], dp[i][j+1]+1)

    return max(dp[0] + dp[-1] + [dp[i][0] for i in range(1, n-1)] + [dp[i][-1] for i in range(1, n-1)])