1289. 下降路径最小和 II
给你一个整数方阵 arr ,定义「非零偏移下降路径」为:从 arr 数组中的每一行选择一个数字,且按顺序选出来的数字中,相邻数字不在原数组的同一列。
请你返回非零偏移下降路径数字和的最小值。
示例 1:
输入:arr = [[1,2,3],[4,5,6],[7,8,9]]
输出:13
解释:
所有非零偏移下降路径包括:
[1,5,9], [1,5,7], [1,6,7], [1,6,8],
[2,4,8], [2,4,9], [2,6,7], [2,6,8],
[3,4,8], [3,4,9], [3,5,7], [3,5,9]
下降路径中数字和最小的是 [1,5,7] ,所以答案是 13 。
提示:
1 <= arr.length == arr[i].length <= 200-99 <= arr[i][j] <= 99
动态规划 困难
思路和最短路径差不多,不过每次状态转移遍历查找上一行的最小值这一过程可以优化,时间复杂度可以优化到O(N)
代码
1. O(N)
class Solution:
def minFallingPathSum(self, arr: List[List[int]]) -> int:
n = len(arr)
for i in range(1, n):
for j in range(n):
t = min(arr[i-1][:j] + arr[i-1][j+1:])
arr[i][j] += t
return min(arr[n-1])
2. 时间优化版
class Solution:
def minFallingPathSum(self, arr: List[List[int]]) -> int:
n = len(arr)
MAX = float('inf')
j1, j2 = -1, -1 # j1记录最小值坐标, j2记录次小值坐标
for j in range(n):
if arr[0][j] < ( MAX if j1 == -1 else arr[0][j1]):
j2, j1 = j1, j
elif arr[0][j] < ( MAX if j2 == -1 else arr[0][j2]):
j2 = j
j3, j4 = j1, j2
for i in range(1, n):
j1, j2 = j3, j4
j3, j4 = -1, -1
for j in range(n):
if j != j1:
arr[i][j] += arr[i-1][j1]
else:
arr[i][j] += arr[i-1][j2]
# 更新本行最小、次小值
if arr[i][j] < ( MAX if j3 == -1 else arr[i][j3]):
j4, j3 = j3, j
elif arr[i][j] < ( MAX if j4 == -1 else arr[i][j4]):
j4 = j
return min(arr[n-1])