leetcode120
经典的动态规划问题,
推导状态转移方程:
确定边界:
C++解法一:
1 class Solution { 2 public: 3 int minimumTotal(vector<vector<int>>& triangle) { 4 //动态规划,创建n*n矩阵,消耗空间n平方 5 int h=triangle.size(); //求三角形高度 6 //可以从底层递推,底层边界如下: 7 int p[h][h]; 8 for(int i=0;i<h;i++){ 9 p[h-1][i]=triangle[h-1][i]; 10 } 11 //开始递推 12 for(int i=h-2;i>=0;i--){ 13 for(int j=0;j<=i;j++){ 14 p[i][j]=min(p[i+1][j],p[i+1][j+1])+triangle[i][j]; 15 } 16 } 17 int res=p[0][0]; 18 return res; 19 } 20 };
本题时间复杂度O(n2),空间复杂度也为O(n2),但空间的消耗是可以节省的,因为最终只需要一个最短路径和;
c++解法二:
因为利用过的triangle不会再被利用,所以直接使用triangle存储
1 class Solution { 2 public: 3 int minimumTotal(vector<vector<int>>& triangle) { 4 //动态规划 5 int h=triangle.size(); //求三角形高度 6 //可以从底层递推 7 for(int i=h-2;i>=0;i--){ 8 for(int j=0;j<=i;j++){ 9 triangle[i][j]=min(triangle[i+1][j],triangle[i+1][j+1])+triangle[i][j]; 10 } 11 } 12 int res=triangle[0][0]; 13 return res; 14 } 15 };
这个例子直接使用了triangle覆盖了原始数据存储,虽然没有消耗额外空间,但个人并不觉得好
C++解法三:
1 class Solution { 2 public: 3 int minimumTotal(vector<vector<int>>& triangle) { 4 //动态规划 5 int h=triangle.size(); //求三角形高度 6 //可以从底层递推 7 int p[h]; 8 for(int i=0;i<h;i++){ 9 p[i]=triangle[h-1][i]; 10 } 11 for(int i=h-2;i>=0;i--){ 12 for(int j=0;j<=i;j++){ 13 p[j]=min(p[j],p[j+1])+triangle[i][j]; 14 } 15 } 16 return p[0]; 17 } 18 };
利用每一次更新p[j]之前,p[j]之前的值全部已经更新,p[j]以及p[j]之后的值没有进行更新,而且递推公式只用到了P[j]以及P[j+1]而这两个都没有变化,所以刚好可以用O(n)的空间进行运算