zoukankan      html  css  js  c++  java
  • 【leetcode】1289. Minimum Falling Path Sum II

    题目如下:

    Given a square grid of integers arr, a falling path with non-zero shifts is a choice of exactly one element from each row of arr, such that no two elements chosen in adjacent rows are in the same column.

    Return the minimum sum of a falling path with non-zero shifts.

    Example 1:

    Input: arr = [[1,2,3],[4,5,6],[7,8,9]]
    Output: 13
    Explanation: 
    The possible falling paths are:
    [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]
    The falling path with the smallest sum is [1,5,7], so the answer is 13.

    Constraints:

    • 1 <= arr.length == arr[i].length <= 200
    • -99 <= arr[i][j] <= 99

    解题思路:记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])
  • 相关阅读:
    素数算法问题
    字符指针和字符数组
    指针引用多维数组
    指针细节整理3
    指针细节整理2
    指针细节整理
    公约数和公倍数
    冒泡排序、选择排序
    如何写出高性能的sql语句?
    并发控制
  • 原文地址:https://www.cnblogs.com/seyjs/p/12041890.html
Copyright © 2011-2022 走看看