LeetCode 120. Triangle 动态规划
来源:互联网 发布:网络系统管理课程 编辑:程序博客网 时间:2024/06/05 23:39
120. Triangle
Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below.
For example, given the following triangle
[
[2],
[3,4],
[6,5,7],
[4,1,8,3]
]The minimum path sum from top to bottom is 11 (i.e., 2 + 3 + 5 + 1 = 11).
Note:
Bonus point if you are able to do this using only O(n) extra space, where n is the total number of rows in the triangle.
题意
给定一个三角形,找到一个最小路径和从顶部到底部,每一次只能移动到下一行相邻的元素。
空间复杂度能是O(n)
思路1
自底向上。动态规划。
求解从上到下最小路径和,那么由底部将每一层到达当前位置的最小路径计算出来,计算方法底层相邻元素取小的并和当前位置元素相加,层层计算,那么最顶层就是最小路径和。
- k层中第i个位置最小路径和
minPath[k][i] = min(minPath[k+1][i]+minPath[k+1][i+1])+triangle[k][i]
代码1
class Solution {public: int minimumTotal(vector<vector<int>>& triangle) { vector<vector<int>> minLen(triangle); //用于保存每一层的最小路径和 //从倒数第二层开始判断 for (int layer = triangle.size() - 2; layer >= 0; layer--) { for (int i = 0; i < triangle[layer].size(); i++) { minLen[layer][i] = min(minLen[layer+1][i], minLen[layer+1][i + 1]) + triangle[layer][i]; } } return minLen[0][0]; }};
- 代码优化,将空间复杂度降低。
- 保存当前行各个位置的最小路径和,到下一次计算可以被边计算边覆盖,节省空间。
- minPath[i] = min(minPath[i]+minPath[i+1])+triangle[k][i]
class Solution {public: int minimumTotal(vector<vector<int>>& triangle) { int res = 0; vector<int> minLen(triangle.back()); //行内最多元素为三角形最底层 for(int layer=triangle.size()-2; layer >= 0; layer--) { for(int i=0;i<triangle[layer].size();i++) { minLen[i] = min(minLen[i],minLen[i+1])+triangle[layer][i]; } } return minLen[0]; }};
思路2
自顶向下,并未使用递归结构。
特除处理是处理每一行中第一个元素:没有左子树为无限大,最后一个元素:没有右子树为无限大。其模拟的结果就是,到达两侧元素的路径最小和就是上一行的第一个元素(最后一个元素)+当前元素。
非两侧的元素,就需要比较相邻的两个元素选择小的一个+当前元素。
就像一颗倒立的二叉树
空间复杂度使用的是三角形数组本身。记忆累加,各个位置存储的都是到达当前位置的最小路径和。
最终将三角形数组的最后一行排序,输出最小值,即为从顶到底的最小路径和。
代码2
- triangle[i][j] = triangle[i][j] + min(triangle[i-1][j-1],triangle[i-1][j]);
class Solution {public: int minimumTotal(vector<vector<int>>& triangle) { for(int i=1;i<triangle.size();i++) { for(int j=0;j<triangle[i].size();j++) { int left = 9999999; int right = 9999999; if(j>0) //第一个元素没有左子树, { left = triangle[i-1][j-1]; } if(j<triangle[i].size()-1) //最后一个元素没有右子树 { right = triangle[i-1][j]; } //非两侧元素 triangle[i][j] = triangle[i][j] + min(left,right); } } sort(triangle.back().begin(), triangle.back().end()); return triangle.back()[0]; }};
思路3
自顶向下的另外一种写发,较思路2较复杂。
其实是思路2是思路3的一种优化,将两侧元素和其余元素统一处理,不需要额外空间。
代码3
class Solution {public: int minimumTotal(vector<vector<int>>& triangle) { vector<int> minLen(triangle.back().size(), triangle[0][0]); //一开始的初始值要确定好了,是必须的等于第一个元素,默认将第一行的值作为初始值 //for循环,一开始从第二行开始,内层for循环必须使用逆序,因为在进行minLen操作,顺序会将之前的值覆盖,只有逆序将上次的结果使用之后 for (int i = 1; i < triangle.size();i++) //行 { /* for (int j = 0; j < triangle[i].size(); j++) //行中有多少元素 { if (j == 0) //直接赋值是行不通的,因为上一次的加结果并未参与到下一行加的计算中,需要+= //minLen[j] += triangle[i-1][0]+triangle[i][j]; minLen[j] += triangle[i][j]; //将上一次的累加结果+当前元素的值,即为当前路径的值 else if (j == triangle[i].size() - 1) minLen[j] += triangle[i][j]; //处理三角形两侧的元素 else minLen[j] = min(minLen[j-1], minLen[j]) + triangle[i][j]; } */ for (int j=triangle[i].size()-1;j>=0;j--) //逆序,否则数据还未被使用,就会被覆盖 { if (j == 0) minLen[j] += triangle[i][j]; //第一个元素可以加直接 + minLen[j] 是因为历史值就存储在minLen[0]中, else if (j == triangle[i].size() - 1) minLen[j] = triangle[i][j] + minLen[j - 1]; //最后的元素必须是+minLen[j-1],这是历史存储的结果,如果是+minLen[j]那么就是一个初始值为第一行第一个元素 else minLen[j] = triangle[i][j] + min(minLen[j - 1], minLen[j]); //更新这一行相同坐标的值,使用了上一行的minLen[j-1],[j]值 } } sort(minLen.begin(), minLen.end()); return minLen[0]; }};
- LeetCode 120. Triangle 动态规划
- LeetCode 120. Triangle 动态规划
- [LeetCode] [动态规划] Triangle
- leetcode-动态规划:Triangle
- leetcode-120-Triangle 动态规划
- leetcode 120.Triangle-杨辉三角形|动态规划
- 120. Triangle 类别:动态规划 难度:medium
- 【LeetCode】120. Triangle 基于C++和Java的分析及解法,动态规划
- Leetcode 120. Triangle 三角形问题(动态规划经典) 解题报告
- 动态规划 triangle
- poj1163The Triangle(动态规划)
- 动态规划----Triangle
- 动态规划入门-Triangle
- LeetCode120. Triangle 动态规划
- LeetCode Triangle Bounus达成 动态规划法解法
- LeetCode -- Triangle 路径求最小和( 动态规划问题)
- 1163 The Triangle 动态规划
- POJ-1163-The Triangle-动态规划
- LINUX用户管理命令
- 关于解决MFC中LPCTSTR以及UNICODE上乱码的方法 在某人的评论中看到的解决方案
- MyBatis快速学习
- 创业路上折腾了十多年,讲讲这些年的经历和感悟——与大家共勉
- 617. Merge Two Binary Trees
- LeetCode 120. Triangle 动态规划
- [项目实训]6.13 contest_modify html文件编写
- Spring Boot集成cache
- 【剑指offer】题8:旋转数组的最小值
- 1059. C语言竞赛(20)
- This document in intended to assist with identifying and resolving system panics related to Solaris
- 【面试二三事】安全岗面试谈关于SQL注入
- java&jsp最简单的注册数据库连接
- 数据库专家:MySQL分片水很深