日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

[Leetcode][第120题][JAVA][三角形最小路径和][动态规划][递归]

發(fā)布時(shí)間:2023/12/10 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [Leetcode][第120题][JAVA][三角形最小路径和][动态规划][递归] 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

【問(wèn)題描述】[中等]

【解答思路】

1. 動(dòng)態(tài)規(guī)劃思路一 自上而下

第 1 步:設(shè)計(jì)狀態(tài)
f[i][j] 表示從三角形頂部走到位置 (i,j) 的最小路徑和
位置(i,j) 指的是三角形中第 i 行第 j 列(均從 00 開(kāi)始編號(hào))的位置
第 2 步:狀態(tài)轉(zhuǎn)移方程

第 3 步:考慮初始化
f[0][0]=c[0][0]
第 4 步:考慮輸出
f[n?1][0] 到 f[n-1][n-1] 中的最大值,其中 n 是三角形的行數(shù)
第 5 步:考慮是否可以狀態(tài)壓縮

時(shí)間復(fù)雜度:O(N^2) 空間復(fù)雜度:O(N^2)

class Solution {public int minimumTotal(List<List<Integer>> triangle) {int n = triangle.size();int[][] f = new int[n][n];f[0][0] = triangle.get(0).get(0);for (int i = 1; i < n; ++i) {f[i][0] = f[i - 1][0] + triangle.get(i).get(0);for (int j = 1; j < i; ++j) {f[i][j] = Math.min(f[i - 1][j - 1], f[i - 1][j]) + triangle.get(i).get(j);}f[i][i] = f[i - 1][i - 1] + triangle.get(i).get(i);}int minTotal = f[n - 1][0];for (int i = 1; i < n; ++i) {minTotal = Math.min(minTotal, f[n - 1][i]);}return minTotal;} }
動(dòng)態(tài)規(guī)劃 + 空間優(yōu)化

時(shí)間復(fù)雜度:O(N^2) 空間復(fù)雜度:O(2N)

class Solution {public int minimumTotal(List<List<Integer>> triangle) {int n = triangle.size();int[][] f = new int[2][n];f[0][0] = triangle.get(0).get(0);for (int i = 1; i < n; ++i) {int curr = i % 2;int prev = 1 - curr;f[curr][0] = f[prev][0] + triangle.get(i).get(0);for (int j = 1; j < i; ++j) {f[curr][j] = Math.min(f[prev][j - 1], f[prev][j]) + triangle.get(i).get(j);}f[curr][i] = f[prev][i - 1] + triangle.get(i).get(i);}int minTotal = f[(n - 1) % 2][0];for (int i = 1; i < n; ++i) {minTotal = Math.min(minTotal, f[(n - 1) % 2][i]);}return minTotal;} }


時(shí)間復(fù)雜度:O(N^2) 空間復(fù)雜度:O(N)

class Solution {public int minimumTotal(List<List<Integer>> triangle) {int n = triangle.size();int[] f = new int[n];f[0] = triangle.get(0).get(0);for (int i = 1; i < n; ++i) {f[i] = f[i - 1] + triangle.get(i).get(i);for (int j = i - 1; j > 0; --j) {f[j] = Math.min(f[j - 1], f[j]) + triangle.get(i).get(j);}f[0] += triangle.get(i).get(0);}int minTotal = f[0];for (int i = 1; i < n; ++i) {minTotal = Math.min(minTotal, f[i]);}return minTotal;} }
2. 動(dòng)態(tài)規(guī)劃 自底向上 (考慮邊界減少)

第 1 步:設(shè)計(jì)狀態(tài)
dp[i][j] 表示從點(diǎn) (i, j)(i,j) 到底邊的最小路徑和。
第 2 步:狀態(tài)轉(zhuǎn)移方程
dp[i][j]=min(dp[i+1][j],dp[i+1][j+1])+triangle[i][j]
第 3 步:考慮初始
dp[i][j] 均為’0’
第 4 步:考慮輸出
dp[0][0]
第 5 步:考慮是否可以狀態(tài)壓縮

時(shí)間復(fù)雜度:O(N^2) 空間復(fù)雜度:O(N^2)

class Solution {public int minimumTotal(List<List<Integer>> triangle) {int n = triangle.size();// dp[i][j] 表示從點(diǎn) (i, j) 到底邊的最小路徑和。int[][] dp = new int[n + 1][n + 1];// 從三角形的最后一行開(kāi)始遞推。for (int i = n - 1; i >= 0; i--) {for (int j = 0; j <= i; j++) {dp[i][j] = Math.min(dp[i + 1][j], dp[i + 1][j + 1]) + triangle.get(i).get(j);}}return dp[0][0];} } ![在這里插入圖片描述](https://img-blog.csdnimg.cn/20200714110356304.png)

時(shí)間復(fù)雜度:O(N^2) 空間復(fù)雜度:O(N)

class Solution {public int minimumTotal(List<List<Integer>> triangle) {int n = triangle.size();int[] dp = new int[n + 1];for (int i = n - 1; i >= 0; i--) {for (int j = 0; j <= i; j++) {dp[j] = Math.min(dp[j], dp[j + 1]) + triangle.get(i).get(j);}}return dp[0];} }
3. 遞歸


暴力搜索會(huì)有大量的重復(fù)計(jì)算,導(dǎo)致 超時(shí),因此在 結(jié)合記憶化數(shù)組進(jìn)行優(yōu)化。

class Solution {public int minimumTotal(List<List<Integer>> triangle) {return dfs(triangle, 0, 0);}private int dfs(List<List<Integer>> triangle, int i, int j) {if (i == triangle.size()) {return 0;}return Math.min(dfs(triangle, i + 1, j), dfs(triangle, i + 1, j + 1)) + triangle.get(i).get(j);} }

遞歸 + 記憶化
時(shí)間復(fù)雜度:O(N^2) 空間復(fù)雜度:O(N^2)

class Solution {Integer[][] memo;public int minimumTotal(List<List<Integer>> triangle) {memo = new Integer[triangle.size()][triangle.size()];return dfs(triangle, 0, 0);}private int dfs(List<List<Integer>> triangle, int i, int j) {if (i == triangle.size()) {return 0;}if (memo[i][j] != null) {return memo[i][j];}return memo[i][j] = Math.min(dfs(triangle, i + 1, j), dfs(triangle, i + 1, j + 1)) + triangle.get(i).get(j);} }

【總結(jié)】

1.動(dòng)態(tài)規(guī)劃流程

第 1 步:設(shè)計(jì)狀態(tài)
第 2 步:狀態(tài)轉(zhuǎn)移方程
第 3 步:考慮初始化
第 4 步:考慮輸出
第 5 步:考慮是否可以狀態(tài)壓縮

2.自下而上 自上而下均可以實(shí)現(xiàn) 哪個(gè)順手使用哪個(gè) 哪個(gè)邊界清晰用哪個(gè)

轉(zhuǎn)載鏈接:https://leetcode-cn.com/problems/triangle/solution/san-jiao-xing-zui-xiao-lu-jing-he-by-leetcode-solu/
轉(zhuǎn)載鏈接:https://leetcode-cn.com/problems/triangle/solution/di-gui-ji-yi-hua-dp-bi-xu-miao-dong-by-sweetiee/

總結(jié)

以上是生活随笔為你收集整理的[Leetcode][第120题][JAVA][三角形最小路径和][动态规划][递归]的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。