设为首页 加入收藏

TOP

Leetcode dfs&dp Triangle
2015-07-20 17:43:15 来源: 作者: 【 】 浏览:2
Tags:Leetcode dfs& Triangle

Triangle

Total Accepted: 17536 Total Submissions: 65508My Submissions

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.



题意:给定一个三角阵,三角阵里每个位置有一个数值。
找到一条由顶到底的路径,使得路径里的数值总和最小。
每次可以向当前位置的下一行的左或右走。
思路1:dfs + 备忘录
在第i行的第j个位置,往下有两种走法的选择,往第i +1行的第j个位置或第j+1位置
在第i+1行的第j个位置或第j+1个位置的子问题与原问题相同,可用dfs递归求解
用一个数组_min[i][j]保存求解过程的值,避免重复计算。
复杂度:时间O(n ^2),空间O(n^2)


思路2:dp + 滚动数组
设dp[i][j] 表示到达第i行第j个位置的路径的最小数值,则状态转移方程为
dp[i][j] = min(dp[i-1][k]) + A[i][j] 其中 dp[i-1][k]表示可到达dp[i][j]状态的上一个状态
在这里 k可以取 j -1 或 j,A[i][j]表示这个位置的值
因为在第i行只需要用到第i-1行的数据所以可以不用保存i-1前面的最优值。
最后只要用到数组 dp[j] 就可以
复杂度:时间O(n^2),空间O(n)

//思路1
vector
  
    > _min, _triangle;
int dfs(int i, int j){
	if(i == _triangle.size() - 1){
		return _triangle[i][j];	
	}
	if(j < 0 || j >= _triangle[i].size()) return INT_MAX;
	if(_min[i][j] != INT_MAX) return _min[i][j]; //某个特殊值表示 dfs(i,j)还没被计算过
	return _min[i][j] = min(dfs(i + 1, j), dfs(i + 1, j + 1)) + _triangle[i][j];
}


int minimumTotal(vector
   
     > &triangle) { if(triangle.empty()) return 0; _triangle = triangle; _min = vector
    
      >(triangle.size(), vector
     
      (triangle[triangle.size() - 1].size(), INT_MAX)); return dfs(0, 0); } //思路2 int minimumTotal(vector
      
        > &triangle) { if(triangle.empty()) return 0; vector
       
         dp(triangle.back().size(), 0); //初始化 int i = 0; for_each(triangle[0].begin(), triangle[0].end(),[&i, &dp](int &v){ dp[i++] = v; }); //迭代更新dp for(i = 1; i < triangle.size(); ++i){ int dp_j_1 = dp[0]; for(int j = 0; j < triangle[i].size(); ++j){ int tem = dp[j]; if(j == triangle[i].size() - 1) dp[j] = dp_j_1; dp[j] = min(dp_j_1 ,dp[j]) + triangle[i][j]; dp_j_1 = tem; } } int _min = INT_MAX; for(int j = 0; j < dp.size(); ++j) _min = min(_min, dp[j]); return _min; } 
       
      
     
    
   
  


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇[ThinkingInC++]46、特定的数据成.. 下一篇POJ 3233 Matrix Power Series

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·C++中智能指针的性能 (2025-12-25 03:49:29)
·如何用智能指针实现c (2025-12-25 03:49:27)
·如何在 C 语言中管理 (2025-12-25 03:20:14)
·C语言和内存管理有什 (2025-12-25 03:20:11)
·为什么C语言从不被淘 (2025-12-25 03:20:08)