生活随笔
收集整理的這篇文章主要介紹了
[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();int[][] dp
= new int[n
+ 1][n
+ 1];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];}
}

時(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ò),歡迎將生活随笔推薦給好友。