120. 三角形最小路径和 (自下而上和自上而下两种解法)

    技术2022-08-11  81

    题目:

    给定一个三角形,找出自顶向下的最小路径和。每一步只能移动到下一行中相邻的结点上。

    相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 + 1 的两个结点。题目链接

    例如,给定三角形:

    [      [2],     [3,4],    [6,5,7],   [4,1,8,3] ] 自顶向下的最小路径和为 11(即,2 + 3 + 5 + 1 = 11)。

    解法1:常规递归,超时

    class Solution { private: void findMini(vector<vector<int>>& triangle, int rows, int row, int col, int sum, int& res) { if (row == rows) { if (sum < res) res = sum; return; } findMini(triangle, rows, row+1, col, sum+triangle[row][col], res); findMini(triangle, rows, row+1, col+1, sum+triangle[row][col], res); } public: int minimumTotal(vector<vector<int>>& triangle) { int rows = triangle.size(); int res = 0x70000000; findMini(triangle, rows, 0, 0, 0, res); return res; } };

     解法2:自下而上  原地修改削枝至根部

    class Solution { public: int minimumTotal(vector<vector<int>>& triangle) { int rows = triangle.size(); if (0 == rows) return -1; for (int i = rows-2; i >= 0; i--) //倒数第二行开始,到第一行 for (int j = 0; j <= i; j++) triangle[i][j] += min(triangle[i+1][j], triangle[i+1][j+1]);//加和下一行下和右下的较小数 return triangle[0][0]; } };

    解法3:从上而下,利用一个辅助数组

    class Solution { public: int minimumTotal(vector<vector<int>>& triangle) { int rows = triangle.size(); if (0 == rows) return -1; vector<int> line(rows); line[0] = triangle[0][0]; for (int i = 1; i < rows; i++) for (int j = i; j >= 0; j--) //从右至左,以防覆盖前面的原数据 if (0 == j) line[j] += triangle[i][j]; else if (i == j) line[j] = line[j-1] + triangle[i][j]; else line[j] = min(line[j-1], line[j]) + triangle[i][j]; for (int i = 1; i < rows; i++) //用line[0]存最小值 if (line[0] > line[i]) line[0] = line[i]; return line[0]; } };

     

    Processed: 0.014, SQL: 9