算法题:三角形最小路径和

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014573686/article/details/89711711

题目

给定一个三角形,找出自顶向下的最小路径和。每一步只能移动到下一行中相邻的结点上。

例如,给定三角形:

[
      [2],
     [3,4],
    [6,5,7],
   [4,1,8,3]
]

自顶向下的最小路径和为 11(即,2 + 3 + 5 + 1 = 11)。
空间复杂度限制为:O(n) n 为三角形的层数

思路

根据题意,可以使用一个大小为 n 的数组存储每一层的累加和,即每到新的一层,计算当前点与上一层累加和中可以取的最小值相加,(因为是相邻节点,每个点所以可取的值最多两个)。
使用大小为 n 的数组存储此值,从第一层往下依次计算,比如 第二层节点 j , 使用 arr 存储每个累加和的话,arr[ j ] = min(arr[ j ],arr[ j - 1]) + val[1][ j ], 但是由于 arr[j - 1]刚计算结束,所以已经被覆盖为新的值,所以结果不正确。

技巧点:从下往上计算每一层的累加和,一方面可以避免覆盖值的问题,另一方面最后arr【0】就是结果的最小值,而不用再去遍历 arr 也就是说,arr【j】 = min(arr【j】,arr【j+1】) + val【j】

代码

#include<iostream>
#include<vector>
using namespace std;

// 三角形最小路径和
// 要求空间复杂度是O(n)  n 为 三角形层数

// 思路: 采用一个数组,存储已经计算好的和,到新的一层后,每个元素与其可以相加的已经计算好的元素的最小值相加 
// 由于空间的限制,使用一个 n 大小的数组存储的时候,会使用被覆盖后的值,所以,从底层往上计算


class Solution {
public:
	inline int min(int a, int b)
	{
		return a < b ? a : b;
	}
	int minimumTotal(vector<vector<int>>& triangle) 
	{
		// 判断
		if (triangle.size() == 0)
		{
			return 0;
		}

		// 初始化为最后一层
		vector<int> arr = triangle[triangle.size() - 1];
		// 从倒数第二层计算
		for (int i = triangle.size() - 2; i >= 0; i--)
		{
			for (int j = 0; j < triangle[i].size(); j++)
			{
				arr[j] = triangle[i][j] + min(arr[j], arr[j + 1]);  // 刚好不会覆盖
			}
		}
		return arr[0];
	}
};

有问题还望指出。

猜你喜欢

转载自blog.csdn.net/u014573686/article/details/89711711