每天一道LeetCode-----杨辉三角从第一行到最后一行的最小路径和
Triangle
原題鏈接Triangle
在楊輝三角中找到一條從第一行到最后一行的路徑,使該路徑和最小,要求每次移動只能移動到下一行的相鄰位置。用二維數組表示,假設當前在triangle[i][j]位置,那么下次只能移動到triangle[i+1][j]和triangle[i+1][j+1]兩個位置
要求空間復雜度為O(n)
第一種方法是在原二維數組上做修改,利用動態規劃的思想,對于某個位置triangle[i][j],它只能通過triangle[i-1][j-1]和triangle[i-1][j]兩個位置移動到,所以可以計算到達triangle[i][j]時的最小路徑和,最終求解到達最后一行的路徑和,然后求最小值
代碼如下
class Solution { public:int minimumTotal(vector<vector<int>>& triangle) {int n = triangle.size();/* 利用triangle[i][j]存儲從triangle[0][0]到達triangle[i][j]的最小路徑和 */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];elsetriangle[i][j] += std::min(triangle[i - 1][j - 1], triangle[i - 1][j]);}}/* 計算最后一個行的最小值 */int total = INT_MAX;for(int j = 0; j < triangle[n - 1].size(); ++j)total = std::min(total, triangle[n - 1][j]);return total;} };不過這種方法會改變原有數組的值,不太提倡
第二種方法是真的是由O(n)的空間完成,當然也是利用動態規劃思想,但是正如上面的方法思路,如果從上到下計算最小值,那么無論如何最后都需要計算一遍最小值,但是如果換個角度想,從最后一行向上到第一行,那么最后求出的值就一個,而無需再求最小值
令dp[j]表示從最后一行到達當前行的第j列的最小值,那么有dp[j] = triangle[i][j] + min(dp[j], dp[j+1])
另外有一個好處是,由于后一行始終比當前行的元素多,所以j+1不存在越界的問題
代碼如下
class Solution { public:int minimumTotal(vector<vector<int>>& triangle) {if(triangle.empty()) return 0;int n = triangle.size();vector<int> dp(triangle[n - 1].begin(), triangle[n - 1].end());for(int i = n - 2; i >= 0; --i){for(int j = 0; j < triangle[i].size(); ++j){dp[j] = triangle[i][j] + std::min(dp[j], dp[j + 1]);}}return dp[0];} };本題主要利用動態規劃的思想求解,必要時可以換個角度思考,比如本題不一定要從上到下,也可以從下到上,反而簡單
總結
以上是生活随笔為你收集整理的每天一道LeetCode-----杨辉三角从第一行到最后一行的最小路径和的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 每天一道LeetCode-----杨辉三
- 下一篇: Redis源码剖析(七)监视功能