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 is11
(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.
我觉得题目需要解析一下。
就是一条寻路的问题,下标为0的,只能跳到下一行下标为0或1的元素。下标为1的只能跳到下一行下标为1或2的元素,以此类推。
题目说的并不清楚,应该给多两个列子。
我个人觉得这道题不应该想其他解法了。正规解法应该是动态规划法了。不能用贪心法了,因为要全局最优解,而贪心法一般只考虑局部最优解。
动态规划法的名字就daunting,给人很高深的感觉,如果说蛮力法和贪心法是少林长拳和罗汉拳这样的基本功,那么动态规划法听起来就像是独孤九剑这样的高级功法了,这里只用破刀式就够了,专破田伯光快刀O(∩_∩)O~
下面是详细注释的程序,仔细看一看会知道主程序段只有那么几句,比较简单了:
class Solution {
public:
int minimumTotal(vector<vector<int> > &triangle) {
if(triangle.empty()) return 0;
//初始化
vector<int > cost;
auto iter = triangle.end() - 1;
//一个元素需要特殊处理
if(iter == triangle.begin())
{
return (*iter)[0];
}
//注意分配内存给vector,然后再使用。不要使用reserve。
int n = (*iter).size();
cost.resize(n-1);
//不需要填写最后一个元素
for(int i = 0; i< (*iter).size()-1; i++)
{
cost[i] = min((*iter)[i+1], (*iter)[i]);
}
iter--;
//特殊情况处理完,进入主程序段
for(; iter != triangle.begin(); iter--)
{
for(int i = 0; i < (*iter).size()-1; i++)
{
cost[i] = min((*iter)[i]+cost[i], (*iter)[i+1]+cost[i+1]);
}
}
return cost[0] + triangle[0][0];
}
};
总结:
主程序段就那么几句,但是作特殊情况处理却花费了大部分的代码,看来特殊情况处理作为一个人编程水平高低的衡量标准之一也不过分!
2014-2-17 update
之前分析了那么多,现在不用那么多分析了,高手可以连打带消地处理特殊情况,代码就更加简练了,O(∩_∩)O哈哈~
直接给出更加简洁的代码--看,无特殊情况处理,即使triangle是空,还是可以准确地返回答案:
//2014-2-17 update
int minimumTotal(vector<vector<int> > &triangle)
{
int *table = new int[triangle.size()+1];
for (int i = 0; i <= triangle.size(); i++) table[i] = 0;
for (int i = triangle.size() - 1; i >= 0 ; i--)
{
for (int j = 0; j < triangle[i].size(); j++)
{
table[j] = triangle[i][j] + min(table[j], table[j+1]);
}
}
return table[0];
}
处理一个特殊情况:
//2014-2-17 update
int minimumTotal(vector<vector<int> > &triangle)
{
if (triangle.empty()) return 0;
vector<int> table(triangle.back());
for (int i = triangle.size() - 2; i >= 0 ; i--)
{
for (int j = 0; j < triangle[i].size(); j++)
{
table[j] = triangle[i][j] + min(table[j], table[j+1]);
}
}
return table[0];
}
除了画图分析之外,还要做到“心中有剑”,写出更加简练的代码。
分享到:
相关推荐
leetcode思维导图-动态规划
leetcode刷题之动态规划
leetcode找零钱问题动态规划 LeetCode 动态规划 一般解法 注意: 递归算法为从高到底, 动态规划算法为从底到高! 找到转移方程 题目 No.124 二叉树中的最大路径和 No.322 零钱兑换 回溯算法 一般解法 注意: 感觉有点...
LeetCode 探索中的初级算法,手写算法,部分题有题目分析思路
leetcode找零钱问题动态规划 2020.10.12开启每日刷题模式。这里记录每日刷题进展与代码目录情况~ 如果对时间复杂度的要求有 \loglog,通常都需要用到二分查找。 动态规划: 数据结构的存储方式只有两种:数组(顺序...
资源LeetCode__动态规划实用知识库分享知识分享
javascript javascript_leetcode面试题解动态规划问题之第494题_题解
javascript javascript_leetcode面试题解动态规划问题之第198题打家劫舍_题解
javascript javascript_leetcode面试题解动态规划问题之第22题括号生成_题解
javascript javascript_leetcode面试题解动态规划问题之第221题最大正方形_题解
javascript javascript_leetcode面试题解动态规划问题之第139题单词拆分_题解
javascript javascript_leetcode面试题解动态规划问题之第64题最小路径和_题解
javascript javascript_leetcode面试题解动态规划问题之第435题无重叠区间_题解
javascript javascript_leetcode面试题解动态规划问题之第279题完全平方数_题解
javascript javascript_leetcode面试题解动态规划问题之第474题一和零_题解
javascript javascript_leetcode面试题解动态规划问题之第70题爬楼梯_题解
javascript javascript_leetcode面试题解动态规划问题之第416题分割等和子集_题解
javascript javascript_leetcode面试题解动态规划问题之第718题最长重复子数组_题解
javascript javascript_leetcode面试题解动态规划问题之第931题下降路径最小和_题解
javascript javascript_leetcode面试题解动态规划问题之第300题最长上升子序列_题解