📜  三角形中的最小和路径

📅  最后修改于: 2021-09-17 07:19:59             🧑  作者: Mango

给定一个数字的三角形结构,找到从上到下的最小路径和。每一步您都可以移动到下一行的相邻数字。

例子 :

Input : 
   2
  3 7
 8 5 6
6 1 9 3
Output : 11
Explanation : 2 + 3 + 5 + 1 = 11

Input :
   3
  6 4
 5 2 7
9 1 8 6
Output : 10
Explanation : 3 + 4 + 2 + 1 = 10

朴素的方法:通过遍历每一条可能的路径来通过朴素的方法。但是,这是代价高昂的。因此,在这里使用动态规划以减少时间复杂度。
有两种方法可以达到解决方案:

1.记忆化——从顶层节点开始,递归遍历每个节点,直到计算出该节点的路径和。然后将结果存储在一个数组中。但这将需要 O(N^2) 空间来维护数组。

2.自下而上——从最底行的节点开始;这些节点的最小路径和是节点本身的值。之后,第k行第i个节点的最小路径和将是其两个孩子的路径和+节点值的最小值,即:

memo[k][i] = min( memo[k+1][i], memo[k+1][i+1]) + A[k][i];

要么
只需将备忘录设置为一维数组,然后更新它
这也将节省空间:

对于第 k 行:

memo[i] = min( memo[i], memo[i+1]) + A[k][i];

以下是上述动态规划方法的实现:

C++
// C++ program for Dynamic
// Programming implementation of
// Min Sum Path in a Triangle
#include 
using namespace std;
 
// Util function to find minimum sum for a path
int minSumPath(vector >& A)
{
    // For storing the result in a 1-D array,
    // and simultaneously updating the result.
    int memo[A.size()];
    int n = A.size() - 1;
 
    // For the bottom row
    for (int i = 0; i < A[n].size(); i++)
        memo[i] = A[n][i];   
 
    // Calculation of the remaining rows,
    // in bottom up manner.
    for (int i = A.size() - 2; i >= 0; i--)
        for (int j = 0; j < A[i].size(); j++)
            memo[j] = A[i][j] + min(memo[j],
                                    memo[j + 1]);
 
    // return the top element
    return memo[0];
}
 
/* Driver program to test above functions */
int main()
{
    vector > A{ { 2 },
                            { 3, 9 },
                            { 1, 6, 7 } };
    cout << minSumPath(A);
    return 0;
}


Java
// Java program for Dynamic
// Programming implementation of
// Min Sum Path in a Triangle
import java.io.*;
import java.util.*;
 
class GFG
{
    static int A[][] = {{2},
                        {3, 9},
                        {1, 6, 7}};
                         
    // Util function to find
    // minimum sum for a path
    static int minSumPath()
    {
        // For storing the result
        // in a 1-D array, and
        // simultaneously updating
        // the result.
        int []memo = new int[A.length];
        int n = A.length - 1;
     
        // For the bottom row
        for (int i = 0;
                 i < A[n].length; i++)
            memo[i] = A[n][i];
     
        // Calculation of the
        // remaining rows, in
        // bottom up manner.
        for (int i = A.length - 2;
                 i >= 0; i--)
            for (int j = 0;
                     j < A[i].length; j++)
                memo[j] = A[i][j] +
                          (int)Math.min(memo[j],
                                   memo[j + 1]);
     
        // return the
        // top element
        return memo[0];
    }
     
    // Driver Code
    public static void main(String args[])
    {
        System.out.print(minSumPath());
    }
}
 
// This code is contributed by
// Manish Shaw (manishshaw1)


Python3
# Python3 program for Dynamic
# Programming implementation of
# Min Sum Path in a Triangle
 
# Util function to find
# minimum sum for a path
def minSumPath(A):
     
    # For storing the result in
    # a 1-D array, and simultaneously
    # updating the result.
    memo = [None] * len(A)
    n = len(A) - 1
     
    # For the bottom row
    for i in range(len(A[n])):
        memo[i] = A[n][i]
 
    # Calculation of the
    # remaining rows,
    # in bottom up manner.
    for i in range(len(A) - 2, -1,-1):
        for j in range( len(A[i])):
            memo[j] = A[i][j] + min(memo[j],
                                    memo[j + 1]);
 
    # return the top element
    return memo[0]
 
# Driver Code
A = [[ 2 ],
    [3, 9 ],
    [1, 6, 7 ]]
print(minSumPath(A))
 
# This code is contributed
# by ChitraNayal


C#
// C# program for Dynamic
// Programming implementation of
// Min Sum Path in a Triangle
using System;
using System.Collections.Generic;
using System.Linq;
 
class GFG {
     
    // Util function to find
    // minimum sum for a path
    static int minSumPath(ref List> A)
    {
         
        // For storing the result in a 1-D array,
        // and simultaneously updating the result.
        int []memo = new int[A.Count];
        int n = A.Count - 1;
     
        // For the bottom row
        for (int i = 0; i < A[n].Count; i++)
            memo[i] = A[n][i];
     
        // Calculation of the remaining rows,
        // in bottom up manner.
        for (int i = A.Count - 2; i >= 0; i--)
            for (int j = 0; j < A[i + 1].Count - 1; j++)
                memo[j] = A[i][j] +
                          (int)Math.Min(memo[j],
                                   memo[j + 1]);
     
        // return the top element
        return memo[0];
    }
     
    // Driver Code
    public static void Main()
    {
        List> A = new List>();
        A.Add(new List {2});
        A.Add(new List {3, 9});
        A.Add(new List {1, 6, 7});
        Console.WriteLine(minSumPath(ref A));
    }
}
 
// This code is contributed by
// Manish Shaw (manishshaw1)


PHP
= 0; $i--)
        for ($j = 0;
             $j < count($A[$i + 1]) - 1; $j++)
            $memo[$j] = $A[$i][$j] +
                        min($memo[$j],
                        $memo[$j + 1]);
 
    // return the
    // top element
    return $memo[0];
}
 
// Driver Code
$A = array(array(2),
           array(3, 9),
           array(1, 6, 7));
echo (minSumPath($A));
 
// This code is contributed
// by Manish Shaw(manishshaw1)
?>


Javascript


输出:
6

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程