给定一个正三角形数组,自顶到底分别有 1,2,3,4,5...,n 个元素,找出自顶向下的最小路径和。
每一步只能移动到下一行的相邻节点上,相邻节点指下行种下标与之相同或下标加一的两个节点。
数据范围:三角形数组行数满足
,数组中的值都满足 
例如当输入[[2],[3,4],[6,5,7],[4,1,8,3]]时,对应的输出为11,
所选的路径如下图所示:
[[10]]
10
[[2],[3,4],[6,5,7],[4,1,8,3]]
11
最小路径是 2 , 3 ,5 , 1
[[1],[-1000,0]]
-999
import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param triangle int整型二维数组 * @return int整型 */ public int minTrace (int[][] triangle) { // write code here int n = triangle.length; for(int i = n - 2; i >= 0; i--){ int m = triangle[i].length; for(int j = 0; j < m; j++){ triangle[i][j] += Math.min(triangle[i + 1][j], triangle[i + 1][j + 1]); } } return triangle[0][0]; } }
int minTrace(vector<vector<int> >& triangle) { // write code here int n = triangle.size(); vector<vector<int> > dp(n, vector<int>(n)); dp[0][0] = triangle[0][0]; for (int i = 1; i < n; ++i) { for (int j = 0; j < triangle[i].size(); ++j) { if (j == 0) { dp[i][0] = dp[i - 1][0] + triangle[i][0]; } else if (j == i) { dp[i][i] = dp[i - 1][i - 1] + triangle[i][i]; } else { dp[i][j] = triangle[i][j] + min(dp[i - 1][j], dp[i - 1][j - 1]); } } } int res = dp[n - 1][0]; for (int i = 1; i < n; ++i) { res = min(res, dp[n - 1][i]); } return res; }
int minTrace(vector<vector<int>> &triangle) // 二维数组 { // write code here int m = triangle.size(); // 行数 vector<vector<int>> dp(m, vector<int>(m, 0)); // 创建二维数组容器,并初始化为0 dp[0][0] = triangle[0][0]; // 确定边界值 // 初始化起点 for (int i = 1; i < m; i++) { for (int j = 0; j <= i; j++)//二维数组的话一般都是两层for循环遍历所有数据 { if (j == 0)//前两部判断都是为了确定边界值,因为只有一行或一列,所以不需要考虑边界值 dp[i][j] = dp[i - 1][j] + triangle[i][j]; else if (j == i) dp[i][j] = dp[i - 1][j - 1] + triangle[i][j]; else dp[i][j] = min(dp[i - 1][j], dp[i - 1][j - 1]) + triangle[i][j]; } } int res = 1e9; for (int i = 0; i < m; i++) { res = min(res, dp[m - 1][i]); } return res; }
public static int minTrace(int[][] triangle) { // write code here if (triangle.length == 1) return triangle[0][0]; // dp[i][j] 表示第 i 层选 triangle[i][j] 时的最小值 int[][] dp = new int[triangle.length][triangle.length]; dp[0][0] = triangle[0][0]; dp[1][0] = dp[0][0] + triangle[1][0]; dp[1][1] = dp[0][0] + triangle[1][1]; // 当第 i 层时, 纵坐标最多为 i for (int i = 2; i < triangle.length; i++) { // 不能记录某一层的最小值是因为当层数增加时,该最小值就不是全局最小值 for (int j = 0; j <= i; j++) { // 第一个元素,则只能是正上方转移过来 if (j == 0) dp[i][j] = triangle[i][j] + dp[i - 1][0]; // 最后一个元素,只能是左上角转移过来 else if (j == i) dp[i][j] = triangle[i][j] + dp[i - 1][j - 1]; // 其余两种可能 else dp[i][j] = triangle[i][j] + Math.min(dp[i - 1][j - 1], dp[i - 1][j]); } } // 从最后一层找到最终最小值 int res = Integer.MAX_VALUE; for (int i = 0; i < dp[dp.length - 1].length; i++) { res = Math.min(res, dp[dp.length - 1][i]); } return res; }
import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param triangle int整型二维数组 * @return int整型 */ public int minTrace (int[][] triangle) { // write code here //当处于triangle[i][j]位置时候,到达该位置的最小路径和为dp[i][j]; int dp[][]=new int[triangle.length][triangle.length]; //初始化dp数组 dp[0][0]=triangle[0][0]; for(int i=1;i<triangle.length;i++){ for(int j=0;j<triangle[i].length;j++){ //当处于该行最左边 if(j==0){ dp[i][j]=dp[i-1][j]+triangle[i][j]; //当处于该行最右边 }else if(i==j){ dp[i][j]=dp[i-1][j-1]+triangle[i][j]; //当处于该行中间 }else{ dp[i][j]=Math.min(dp[i-1][j]+triangle[i][j],dp[i-1][j-1]+triangle[i][j]); } } } //寻找最后一行最大值 int min=Integer.MAX_VALUE; for(int i=0;i<triangle.length;i++){ if(dp[triangle.length-1][i]<min){ min=dp[triangle.length-1][i]; } } return min; } }
int minTrace(vector<vector<int> >& triangle) { int n = triangle.size(); for (int i = 1; i < n; ++i) { for (int j = 0; j < triangle[i].size(); ++j) { if (j == 0) triangle[i][j] += triangle[i - 1][j]; else if (j == triangle[i].size() - 1) triangle[i][j] += triangle[i - 1][j - 1]; else { triangle[i][j] += min(triangle[i - 1][j - 1], triangle[i - 1][j]); } } } int res = triangle[n - 1][0]; for (int i = 0; i < triangle[n - 1].size(); ++i) { res = min(res, triangle[n - 1][i]); } }
class Solution { public: void sol(vector<vector<int> >& tri, int i, int j, int& cur, vector<int>& all_path) { if (i == tri.size() - 1) { all_path.push_back(cur); return; } cur += (tri[i + 1][j]); sol(tri, i + 1, j, cur, all_path); cur -= (tri[i + 1][j]); cur += (tri[i + 1][j + 1]); sol(tri, i + 1, j + 1, cur, all_path); cur -= (tri[i + 1][j + 1]); } /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param triangle int整型vector<vector<>> * @return int整型 */ int minTrace(vector<vector<int> >& triangle) { // write code here int cur=0; cur += (triangle[0][0]); vector<int> all_path; sol(triangle, 0, 0, cur, all_path); // cout << "sum.size()=" << all_path.size(); sort(all_path.begin(), all_path.end()); return all_path.front(); } }; 请教大佬为什么会超内存呢
int minTrace(int** triangle, int triangleRowLen, int* triangleColLen ) { int dp[201][200]; dp[0][0]=triangle[0][0]; for (int i=1; i<triangleRowLen; i++) { dp[i][0]=dp[i-1][0]+triangle[i][0]; } for (int i=1; i<triangleRowLen; i++) { for (int j=1; j<triangleColLen[i]; j++) { if (j==triangleColLen[i]-1) { dp[i][j]=dp[i-1][j-1]+triangle[i][j]; } else { dp[i][j]=(dp[i-1][j-1]<dp[i-1][j]?dp[i-1][j-1]:dp[i-1][j])+triangle[i][j]; } } } int min=dp[triangleRowLen-1][0]; for (int i=0; i<triangleColLen[triangleRowLen-1]; i++) { if(dp[triangleRowLen-1][i]<min){ min=dp[triangleRowLen-1][i]; } } return min; }
function minTrace( triangle ) { // write code here let results=[triangle[0][0]] let len=triangle.length for(let i=1;i<len;i++){ let res=[] triangle[i].forEach((item,j)=>{ const stepLen=triangle[i].length-1 if(j===0){ res.push(results[0]+item) }else if(j===stepLen){ const lastStepLen=results.length-1 res.push(results[lastStepLen]+item) }else{ res.push(Math.min(results[j],results[j-1])+item) } }) results=res } return Math.min(...results) }
#include <vector> class Solution { public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param triangle int整型vector<vector<>> * @return int整型 */ int minTrace(vector<vector<int> >& triangle) { // write code here // 总行数 int n=triangle.size(); for(int i=n-2;i>=0;i--){ for(int j=triangle[i].size()-1;j>=0;j--){ triangle[i][j]+=min(triangle[i+1][j],triangle[i+1][j+1]); } } return triangle[0][0]; } };
/** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param triangle int整型二维数组 * @param triangleRowLen int triangle数组行数 * @param triangleColLen int* triangle数组列数 * @return int整型 */ int minTrace(int** triangle, int triangleRowLen, int* triangleColLen ) { int dp[201][200] = {0}; int min=0; dp[0][0] = triangle[0][0]; //先记录整个第一列的dp值 for(int i=1; i<triangleRowLen; i++) dp[i][0] = dp[i-1][0] + triangle[i][0]; //然后每一个数都是起点到该店的最小路径,为上一个或前一个的最小路径加上自己 for(int i=1; i<triangleRowLen; i++) { for(int j=1; j<(triangleColLen[triangleRowLen-1]); j++) { if(j == triangleColLen[i]-1) { dp[i][j] = dp[i-1][j-1]+triangle[i][j]; continue; } min = dp[i-1][j]<dp[i-1][j-1]?dp[i-1][j]:dp[i-1][j-1]; dp[i][j] = min+triangle[i][j]; } } min = dp[triangleRowLen-1][0]; for(int j=0; j<(triangleColLen[triangleRowLen-1]); j++) { if(dp[triangleRowLen-1][j]<min) min = dp[triangleRowLen-1][j]; } return min; // write code here }
# # 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 # # # @param triangle int整型二维数组 # @return int整型 # class Solution: def minTrace(self , triangle: List[List[int]]) -> int: # write code here dp = triangle.copy() for i in range(1, len(triangle)): for j in range(len(triangle[i])): if j == len(triangle[i]) - 1: dp[i][j] = dp[i-1][j-1] + triangle[i][j] elif j == 0: dp[i][j] = dp[i-1][j] + triangle[i][j] else: dp[i][j] = min(dp[i-1][j-1], dp[i-1][j]) + triangle[i][j] return min(dp[-1])
#include <climits> class Solution { public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param triangle int整型vector<vector<>> * @return int整型 */ int minTrace(vector<vector<int> >& triangle) { // write code here int n = triangle.size(); vector<int> dp(n, INT_MAX); dp[0] = triangle[0][0]; for(int i=1; i<n; i++){ for(int j=i; j>0; j--){ dp[j] = min(dp[j],dp[j-1])+triangle[i][j]; } dp[0] = dp[0]+triangle[i][0]; } int res = INT_MAX; for(int v : dp){ if(v<res) res = v; } return res; } };
#include <climits> class Solution { public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param triangle int整型vector<vector<>> * @return int整型 */ int minTrace(vector<vector<int> >& triangle) { int m = triangle.size(); vector<vector<int>> dp(m + 1, vector<int>(m + 1, INT_MAX)); dp[0][0] = dp[0][1] = 0; for (int i = 1; i <= m; i++) { for (int j = 1; j <= i; j++) { dp[i][j] = min(dp[i - 1][j], dp[i - 1][j - 1]) + triangle[i - 1][j - 1]; } } int ret = INT_MAX; for (int i = 1; i <= m; i++) { ret = min(ret, dp[m][i]); } return ret; } };
#include <algorithm> class Solution { public: int minTrace(vector<vector<int> >& triangle) { vector<vector<int>> minPathSum(triangle); int row=triangle.size(); //从最后一行开始向上推导 for(int i=row-2;i>=0;--i) { for(int j=0;j<=i;++j) { minPathSum[i][j]=min(minPathSum[i+1][j+1],minPathSum[i+1][j])+triangle[i][j]; } } return minPathSum[0][0]; } };
class Solution: def minTrace(self , triangle: List[List[int]]) -> int: # 定义dp[i][j]为从下往上到第[i,j]个元素时的最小路径和 # 最后结果为dp[0][0] # dp转移方程为: dp[i][j] = min(dp[i+1][j], dp[i+1][j+1]) + triangle[i][j] # 初始状态: dp[m-1][j] = triangle[m-1][j] m, n = len(triangle), len(triangle[-1]) dp = [[0 for _ in range(n)] for _ in range(m)] for j in range(n): dp[m-1][j] = triangle[m-1][j] for i in range(m-2, -1, -1): for j in range(i+1): dp[i][j] = min(dp[i+1][j], dp[i+1][j+1]) + triangle[i][j] return dp[0][0]
using System; using System.Collections.Generic; class Solution { public int minTrace(List<List<int>> triangle) { // f[y][x]表示到点(x, y)的最短路径长度 // f[y][x] = triangle[y][x] + min(f[y - 1][x - 1]+ f[y - 1][x]) List<List<int>> dp = triangle; for (int y = 1; y < dp.Count; ++y) { dp[y][0] += dp[y - 1][0]; for (int x = 1; x < dp[y].Count - 1; ++x) dp[y][x] += Math.Min(dp[y - 1][x - 1], dp[y - 1][x]); dp[y][dp[y].Count - 1] += dp[y - 1][dp[y].Count - 2]; } int minDist = dp[dp.Count - 1][0]; for (int x = 1; x < dp[dp.Count - 1].Count; ++x) minDist = Math.Min(minDist, dp[dp.Count - 1][x]); return minDist; } }