题目如下:
解题思路:记dp[i][j]为第i行取第j个元素时,在0~i行区间内获得的最小值。那么显然有dp[i][j] = min(dp[i][j],dp[i-1][k] + arr[i][j]) ,其中j != k。这样的话时间复杂度是O(n),超时了。再仔细想想,其实对于任意一个j,在dp[i-1]中只要找出最小值即可,当然最小值的所在的列不能和j相同。那么只需要记录dp[i-1]行中的最小值和次小值,如果最小值的下标和j相同就取次小值,否则取最小值。
代码如下:
class Solution(object): def minFallingPathSum(self, arr): """ :type arr: List[List[int]] :rtype: int """ dp = [[float('inf')] * len(arr) for _ in arr] for i in range(len(arr)): dp[0][i] = arr[0][i] def getMin(arr): min_val = float('inf') min_inx = 0 for i in range(len(arr)): if min_val > arr[i]: min_val = arr[i] min_inx = i return (min_val,min_inx) def getSecMin(arr,min_inx): sec_min_val = float('inf') sec_min_inx = 0 for i in range(len(arr)): if i == min_inx:continue if sec_min_val > arr[i]: sec_min_val = arr[i] sec_min_inx = i return (sec_min_val,sec_min_inx) for i in range(1,len(arr)): min_val, min_inx = getMin(dp[i-1]) sec_min_val, sec_min_inx = getSecMin(dp[i-1],min_inx) for j in range(len(arr)): if j == min_inx: dp[i][j] = min(dp[i][j],dp[i-1][sec_min_inx] + arr[i][j]) else: dp[i][j] = min(dp[i][j], dp[i - 1][min_inx] + arr[i][j]) return min(dp[-1])