mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-08 16:54:50 +08:00
Merge branch 'master' of github.com:zhangzw001/leetcode-master
This commit is contained in:
@ -384,9 +384,12 @@
|
|||||||
54. [动态规划:最长回文子序列](./problems/0516.最长回文子序列.md)
|
54. [动态规划:最长回文子序列](./problems/0516.最长回文子序列.md)
|
||||||
55. [动态规划总结篇](./problems/动态规划总结篇.md)
|
55. [动态规划总结篇](./problems/动态规划总结篇.md)
|
||||||
|
|
||||||
|
|
||||||
(持续更新中....)
|
(持续更新中....)
|
||||||
|
|
||||||
|
## 单调栈
|
||||||
|
|
||||||
|
1. [每日温度](./problems/0739.每日温度.md)
|
||||||
|
|
||||||
## 图论
|
## 图论
|
||||||
|
|
||||||
## 十大排序
|
## 十大排序
|
||||||
|
@ -123,7 +123,19 @@ Java:
|
|||||||
```
|
```
|
||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
```python
|
||||||
|
class Solution:
|
||||||
|
def maxSubArray(self, nums: List[int]) -> int:
|
||||||
|
if len(nums) == 0:
|
||||||
|
return 0
|
||||||
|
dp = [0] * len(nums)
|
||||||
|
dp[0] = nums[0]
|
||||||
|
result = dp[0]
|
||||||
|
for i in range(1, len(nums)):
|
||||||
|
dp[i] = max(dp[i-1] + nums[i], nums[i]) #状态转移公式
|
||||||
|
result = max(result, dp[i]) #result 保存dp[i]的最大值
|
||||||
|
return result
|
||||||
|
```
|
||||||
|
|
||||||
Go:
|
Go:
|
||||||
|
|
||||||
|
@ -308,6 +308,27 @@ func uniquePaths(m int, n int) int {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Javascript:
|
||||||
|
```Javascript
|
||||||
|
var uniquePaths = function(m, n) {
|
||||||
|
const dp = Array(m).fill().map(item => Array(n))
|
||||||
|
|
||||||
|
for (let i = 0; i < m; ++i) {
|
||||||
|
dp[i][0] = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < n; ++i) {
|
||||||
|
dp[0][i] = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 1; i < m; ++i) {
|
||||||
|
for (let j = 1; j < n; ++j) {
|
||||||
|
dp[i][j] = dp[i - 1][j] + dp[i][j - 1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dp[m - 1][n - 1]
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
-----------------------
|
-----------------------
|
||||||
|
@ -279,6 +279,30 @@ func uniquePathsWithObstacles(obstacleGrid [][]int) int {
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Javascript
|
||||||
|
``` Javascript
|
||||||
|
var uniquePathsWithObstacles = function(obstacleGrid) {
|
||||||
|
const m = obstacleGrid.length
|
||||||
|
const n = obstacleGrid[0].length
|
||||||
|
const dp = Array(m).fill().map(item => Array(n).fill(0))
|
||||||
|
|
||||||
|
for (let i = 0; i < m && obstacleGrid[i][0] === 0; ++i) {
|
||||||
|
dp[i][0] = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < n && obstacleGrid[0][i] === 0; ++i) {
|
||||||
|
dp[0][i] = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 1; i < m; ++i) {
|
||||||
|
for (let j = 1; j < n; ++j) {
|
||||||
|
dp[i][j] = obstacleGrid[i][j] === 1 ? 0 : dp[i - 1][j] + dp[i][j - 1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dp[m - 1][n - 1]
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
-----------------------
|
-----------------------
|
||||||
|
@ -148,7 +148,22 @@ Java:
|
|||||||
|
|
||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
```python
|
||||||
|
class Solution:
|
||||||
|
def numDistinct(self, s: str, t: str) -> int:
|
||||||
|
dp = [[0] * (len(t)+1) for _ in range(len(s)+1)]
|
||||||
|
for i in range(len(s)):
|
||||||
|
dp[i][0] = 1
|
||||||
|
for j in range(1, len(t)):
|
||||||
|
dp[0][j] = 0
|
||||||
|
for i in range(1, len(s)+1):
|
||||||
|
for j in range(1, len(t)+1):
|
||||||
|
if s[i-1] == t[j-1]:
|
||||||
|
dp[i][j] = dp[i-1][j-1] + dp[i-1][j]
|
||||||
|
else:
|
||||||
|
dp[i][j] = dp[i-1][j]
|
||||||
|
return dp[-1][-1]
|
||||||
|
```
|
||||||
|
|
||||||
Go:
|
Go:
|
||||||
|
|
||||||
|
@ -244,6 +244,47 @@ class Solution { // 动态规划解法
|
|||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
|
||||||
|
> 贪心法:
|
||||||
|
```python
|
||||||
|
class Solution:
|
||||||
|
def maxProfit(self, prices: List[int]) -> int:
|
||||||
|
low = float("inf")
|
||||||
|
result = 0
|
||||||
|
for i in range(len(prices)):
|
||||||
|
low = min(low, prices[i]) #取最左最小价格
|
||||||
|
result = max(result, prices[i] - low) #直接取最大区间利润
|
||||||
|
return result
|
||||||
|
```
|
||||||
|
|
||||||
|
> 动态规划:版本一
|
||||||
|
```python
|
||||||
|
class Solution:
|
||||||
|
def maxProfit(self, prices: List[int]) -> int:
|
||||||
|
length = len(prices)
|
||||||
|
if len == 0:
|
||||||
|
return 0
|
||||||
|
dp = [[0] * 2 for _ in range(length)]
|
||||||
|
dp[0][0] = -prices[0]
|
||||||
|
dp[0][1] = 0
|
||||||
|
for i in range(1, length):
|
||||||
|
dp[i][0] = max(dp[i-1][0], -prices[i])
|
||||||
|
dp[i][1] = max(dp[i-1][1], prices[i] + dp[i-1][0])
|
||||||
|
return dp[-1][1]
|
||||||
|
```
|
||||||
|
|
||||||
|
> 动态规划:版本二
|
||||||
|
```python
|
||||||
|
class Solution:
|
||||||
|
def maxProfit(self, prices: List[int]) -> int:
|
||||||
|
length = len(prices)
|
||||||
|
dp = [[0] * 2 for _ in range(2)] #注意这里只开辟了一个2 * 2大小的二维数组
|
||||||
|
dp[0][0] = -prices[0]
|
||||||
|
dp[0][1] = 0
|
||||||
|
for i in range(1, length):
|
||||||
|
dp[i % 2][0] = max(dp[(i-1) % 2][0], -prices[i])
|
||||||
|
dp[i % 2][1] = max(dp[(i-1) % 2][1], prices[i] + dp[(i-1) % 2][0])
|
||||||
|
return dp[(length-1) % 2][1]
|
||||||
|
```
|
||||||
|
|
||||||
Go:
|
Go:
|
||||||
```Go
|
```Go
|
||||||
|
@ -171,6 +171,33 @@ class Solution
|
|||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
|
||||||
|
> 版本一:
|
||||||
|
```python
|
||||||
|
class Solution:
|
||||||
|
def maxProfit(self, prices: List[int]) -> int:
|
||||||
|
length = len(prices)
|
||||||
|
dp = [[0] * 2 for _ in range(length)]
|
||||||
|
dp[0][0] = -prices[0]
|
||||||
|
dp[0][1] = 0
|
||||||
|
for i in range(1, length):
|
||||||
|
dp[i][0] = max(dp[i-1][0], dp[i-1][1] - prices[i]) #注意这里是和121. 买卖股票的最佳时机唯一不同的地方
|
||||||
|
dp[i][1] = max(dp[i-1][1], dp[i-1][0] + prices[i])
|
||||||
|
return dp[-1][1]
|
||||||
|
```
|
||||||
|
|
||||||
|
> 版本二:
|
||||||
|
```python
|
||||||
|
class Solution:
|
||||||
|
def maxProfit(self, prices: List[int]) -> int:
|
||||||
|
length = len(prices)
|
||||||
|
dp = [[0] * 2 for _ in range(2)] #注意这里只开辟了一个2 * 2大小的二维数组
|
||||||
|
dp[0][0] = -prices[0]
|
||||||
|
dp[0][1] = 0
|
||||||
|
for i in range(1, length):
|
||||||
|
dp[i % 2][0] = max(dp[(i-1) % 2][0], dp[(i-1) % 2][1] - prices[i])
|
||||||
|
dp[i % 2][1] = max(dp[(i-1) % 2][1], dp[(i-1) % 2][0] + prices[i])
|
||||||
|
return dp[(length-1) % 2][1]
|
||||||
|
```
|
||||||
|
|
||||||
Go:
|
Go:
|
||||||
|
|
||||||
|
@ -229,6 +229,40 @@ class Solution { // 动态规划
|
|||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
|
||||||
|
> 版本一:
|
||||||
|
```python
|
||||||
|
class Solution:
|
||||||
|
def maxProfit(self, prices: List[int]) -> int:
|
||||||
|
if len(prices) == 0:
|
||||||
|
return 0
|
||||||
|
dp = [[0] * 5 for _ in range(len(prices))]
|
||||||
|
dp[0][1] = -prices[0]
|
||||||
|
dp[0][3] = -prices[0]
|
||||||
|
for i in range(1, len(prices)):
|
||||||
|
dp[i][0] = dp[i-1][0]
|
||||||
|
dp[i][1] = max(dp[i-1][1], dp[i-1][0] - prices[i])
|
||||||
|
dp[i][2] = max(dp[i-1][2], dp[i-1][1] + prices[i])
|
||||||
|
dp[i][3] = max(dp[i-1][3], dp[i-1][2] - prices[i])
|
||||||
|
dp[i][4] = max(dp[i-1][4], dp[i-1][3] + prices[i])
|
||||||
|
return dp[-1][4]
|
||||||
|
```
|
||||||
|
|
||||||
|
> 版本二:
|
||||||
|
```python
|
||||||
|
class Solution:
|
||||||
|
def maxProfit(self, prices: List[int]) -> int:
|
||||||
|
if len(prices) == 0:
|
||||||
|
return 0
|
||||||
|
dp = [0] * 5
|
||||||
|
dp[1] = -prices[0]
|
||||||
|
dp[3] = -prices[0]
|
||||||
|
for i in range(1, len(prices)):
|
||||||
|
dp[1] = max(dp[1], dp[0] - prices[i])
|
||||||
|
dp[2] = max(dp[2], dp[1] + prices[i])
|
||||||
|
dp[3] = max(dp[3], dp[2] - prices[i])
|
||||||
|
dp[4] = max(dp[4], dp[3] + prices[i])
|
||||||
|
return dp[4]
|
||||||
|
```
|
||||||
|
|
||||||
Go:
|
Go:
|
||||||
|
|
||||||
|
@ -212,6 +212,20 @@ class Solution { //动态规划
|
|||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
|
||||||
|
```python
|
||||||
|
class Solution:
|
||||||
|
def maxProfit(self, k: int, prices: List[int]) -> int:
|
||||||
|
if len(prices) == 0:
|
||||||
|
return 0
|
||||||
|
dp = [[0] * (2*k+1) for _ in range(len(prices))]
|
||||||
|
for j in range(1, 2*k, 2):
|
||||||
|
dp[0][j] = -prices[0]
|
||||||
|
for i in range(1, len(prices)):
|
||||||
|
for j in range(0, 2*k-1, 2):
|
||||||
|
dp[i][j+1] = max(dp[i-1][j+1], dp[i-1][j] - prices[i])
|
||||||
|
dp[i][j+2] = max(dp[i-1][j+2], dp[i-1][j+1] + prices[i])
|
||||||
|
return dp[-1][2*k]
|
||||||
|
```
|
||||||
|
|
||||||
Go:
|
Go:
|
||||||
|
|
||||||
|
@ -130,7 +130,20 @@ class Solution {
|
|||||||
```
|
```
|
||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
```python
|
||||||
|
class Solution:
|
||||||
|
def lengthOfLIS(self, nums: List[int]) -> int:
|
||||||
|
if len(nums) <= 1:
|
||||||
|
return len(nums)
|
||||||
|
dp = [1] * len(nums)
|
||||||
|
result = 0
|
||||||
|
for i in range(1, len(nums)):
|
||||||
|
for j in range(0, i):
|
||||||
|
if nums[i] > nums[j]:
|
||||||
|
dp[i] = max(dp[i], dp[j] + 1)
|
||||||
|
result = max(result, dp[i]) #取长的子序列
|
||||||
|
return result
|
||||||
|
```
|
||||||
|
|
||||||
Go:
|
Go:
|
||||||
```go
|
```go
|
||||||
|
@ -189,6 +189,21 @@ class Solution {
|
|||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
|
||||||
|
```python
|
||||||
|
class Solution:
|
||||||
|
def maxProfit(self, prices: List[int]) -> int:
|
||||||
|
n = len(prices)
|
||||||
|
if n == 0:
|
||||||
|
return 0
|
||||||
|
dp = [[0] * 4 for _ in range(n)]
|
||||||
|
dp[0][0] = -prices[0] #持股票
|
||||||
|
for i in range(1, n):
|
||||||
|
dp[i][0] = max(dp[i-1][0], max(dp[i-1][3], dp[i-1][1]) - prices[i])
|
||||||
|
dp[i][1] = max(dp[i-1][1], dp[i-1][3])
|
||||||
|
dp[i][2] = dp[i-1][0] + prices[i]
|
||||||
|
dp[i][3] = dp[i-1][2]
|
||||||
|
return max(dp[n-1][3], dp[n-1][1], dp[n-1][2])
|
||||||
|
```
|
||||||
|
|
||||||
Go:
|
Go:
|
||||||
|
|
||||||
|
@ -226,7 +226,25 @@ class Solution:
|
|||||||
|
|
||||||
Go:
|
Go:
|
||||||
|
|
||||||
|
Javascript:
|
||||||
|
```Javascript
|
||||||
|
var reconstructQueue = function(people) {
|
||||||
|
let queue = []
|
||||||
|
people.sort((a, b ) => {
|
||||||
|
if(b[0] !== a[0]) {
|
||||||
|
return b[0] - a[0]
|
||||||
|
} else {
|
||||||
|
return a[1] - b[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
for(let i = 0; i < people.length; i++) {
|
||||||
|
queue.splice(people[i][1], 0, people[i])
|
||||||
|
}
|
||||||
|
return queue
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
-----------------------
|
-----------------------
|
||||||
|
@ -175,7 +175,24 @@ class Solution:
|
|||||||
|
|
||||||
Go:
|
Go:
|
||||||
|
|
||||||
|
Javascript:
|
||||||
|
```Javascript
|
||||||
|
var findMinArrowShots = function(points) {
|
||||||
|
points.sort((a, b) => {
|
||||||
|
return a[0] - b[0]
|
||||||
|
})
|
||||||
|
let result = 1
|
||||||
|
for(let i = 1; i < points.length; i++) {
|
||||||
|
if(points[i][0] > points[i - 1][1]) {
|
||||||
|
result++
|
||||||
|
} else {
|
||||||
|
points[i][1] = Math.min(points[i - 1][1], points[i][1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
-----------------------
|
-----------------------
|
||||||
|
@ -184,6 +184,37 @@ Java:
|
|||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
|
||||||
|
> 动态规划:
|
||||||
|
```python
|
||||||
|
class Solution:
|
||||||
|
def findLengthOfLCIS(self, nums: List[int]) -> int:
|
||||||
|
if len(nums) == 0:
|
||||||
|
return 0
|
||||||
|
result = 1
|
||||||
|
dp = [1] * len(nums)
|
||||||
|
for i in range(len(nums)-1):
|
||||||
|
if nums[i+1] > nums[i]: #连续记录
|
||||||
|
dp[i+1] = dp[i] + 1
|
||||||
|
result = max(result, dp[i+1])
|
||||||
|
return result
|
||||||
|
```
|
||||||
|
|
||||||
|
> 贪心法:
|
||||||
|
```python
|
||||||
|
class Solution:
|
||||||
|
def findLengthOfLCIS(self, nums: List[int]) -> int:
|
||||||
|
if len(nums) == 0:
|
||||||
|
return 0
|
||||||
|
result = 1 #连续子序列最少也是1
|
||||||
|
count = 1
|
||||||
|
for i in range(len(nums)-1):
|
||||||
|
if nums[i+1] > nums[i]: #连续记录
|
||||||
|
count += 1
|
||||||
|
else: #不连续,count从头开始
|
||||||
|
count = 1
|
||||||
|
result = max(result, count)
|
||||||
|
return result
|
||||||
|
```
|
||||||
|
|
||||||
Go:
|
Go:
|
||||||
|
|
||||||
|
@ -139,7 +139,17 @@ public int maxProfit(int[] prices, int fee) {
|
|||||||
```
|
```
|
||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
```python
|
||||||
|
class Solution:
|
||||||
|
def maxProfit(self, prices: List[int], fee: int) -> int:
|
||||||
|
n = len(prices)
|
||||||
|
dp = [[0] * 2 for _ in range(n)]
|
||||||
|
dp[0][0] = -prices[0] #持股票
|
||||||
|
for i in range(1, n):
|
||||||
|
dp[i][0] = max(dp[i-1][0], dp[i-1][1] - prices[i])
|
||||||
|
dp[i][1] = max(dp[i-1][1], dp[i-1][0] + prices[i] - fee)
|
||||||
|
return max(dp[-1][0], dp[-1][1])
|
||||||
|
```
|
||||||
|
|
||||||
Go:
|
Go:
|
||||||
|
|
||||||
|
@ -158,6 +158,36 @@ Java:
|
|||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
|
||||||
|
> 动态规划:
|
||||||
|
```python
|
||||||
|
class Solution:
|
||||||
|
def findLength(self, A: List[int], B: List[int]) -> int:
|
||||||
|
dp = [[0] * (len(B)+1) for _ in range(len(A)+1)]
|
||||||
|
result = 0
|
||||||
|
for i in range(1, len(A)+1):
|
||||||
|
for j in range(1, len(B)+1):
|
||||||
|
if A[i-1] == B[j-1]:
|
||||||
|
dp[i][j] = dp[i-1][j-1] + 1
|
||||||
|
result = max(result, dp[i][j])
|
||||||
|
return result
|
||||||
|
```
|
||||||
|
|
||||||
|
> 动态规划:滚动数组
|
||||||
|
```python
|
||||||
|
class Solution:
|
||||||
|
def findLength(self, A: List[int], B: List[int]) -> int:
|
||||||
|
dp = [0] * (len(B) + 1)
|
||||||
|
result = 0
|
||||||
|
for i in range(1, len(A)+1):
|
||||||
|
for j in range(len(B), 0, -1):
|
||||||
|
if A[i-1] == B[j-1]:
|
||||||
|
dp[j] = dp[j-1] + 1
|
||||||
|
else:
|
||||||
|
dp[j] = 0 #注意这里不相等的时候要有赋0的操作
|
||||||
|
result = max(result, dp[j])
|
||||||
|
return result
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
Go:
|
Go:
|
||||||
```Go
|
```Go
|
||||||
|
196
problems/0739.每日温度.md
Normal file
196
problems/0739.每日温度.md
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||||
|
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||||
|
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||||
|
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||||
|
</p>
|
||||||
|
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||||
|
|
||||||
|
# 739. 每日温度
|
||||||
|
|
||||||
|
|
||||||
|
https://leetcode-cn.com/problems/daily-temperatures/
|
||||||
|
|
||||||
|
请根据每日 气温 列表,重新生成一个列表。对应位置的输出为:要想观测到更高的气温,至少需要等待的天数。如果气温在这之后都不会升高,请在该位置用 0 来代替。
|
||||||
|
|
||||||
|
例如,给定一个列表 temperatures = [73, 74, 75, 71, 69, 72, 76, 73],你的输出应该是 [1, 1, 4, 2, 1, 1, 0, 0]。
|
||||||
|
|
||||||
|
提示:气温 列表长度的范围是 [1, 30000]。每个气温的值的均为华氏度,都是在 [30, 100] 范围内的整数。
|
||||||
|
|
||||||
|
|
||||||
|
## 思路
|
||||||
|
|
||||||
|
首先想到的当然是暴力解法,两层for循环,把至少需要等待的天数就搜出来了。时间复杂度是O(n^2)
|
||||||
|
|
||||||
|
那么接下来在来看看使用单调栈的解法。
|
||||||
|
|
||||||
|
那有同学就问了,我怎么能想到用单调栈呢? 什么时候用单调栈呢?
|
||||||
|
|
||||||
|
**通常是一维数组,要寻找任一个元素的右边或者左边第一个比自己大或者小的元素的位置,此时我们就要想到可以用单调栈了**。
|
||||||
|
|
||||||
|
时间复杂度为O(n)。
|
||||||
|
|
||||||
|
例如本题其实就是找找到一个元素右边第一个比自己大的元素。
|
||||||
|
|
||||||
|
此时就应该想到用单调栈了。
|
||||||
|
|
||||||
|
那么单调栈的原理是什么呢?为什么时间复杂度是O(n)就可以找到每一个元素的右边第一个比它大的元素位置呢?
|
||||||
|
|
||||||
|
单调栈的本质是空间换时间,因为在遍历的过程中需要用一个栈来记录右边第一个比当前元素的元素,优点是只需要遍历一次。
|
||||||
|
|
||||||
|
|
||||||
|
在使用单调栈的时候首先要明确如下几点:
|
||||||
|
|
||||||
|
1. 单调栈里存放的元素是什么?
|
||||||
|
|
||||||
|
单调栈里只需要存放元素的下标i就可以了,如果需要使用对应的元素,直接T[i]就可以获取。
|
||||||
|
|
||||||
|
2. 单调栈里元素是递增呢? 还是递减呢?
|
||||||
|
|
||||||
|
**注意一下顺序为 从栈头到栈底的顺序**,因为单纯的说从左到右或者从前到后,不说栈头朝哪个方向的话,大家一定会越看越懵。
|
||||||
|
|
||||||
|
|
||||||
|
这里我们要使用递增循序(再强调一下是指从栈头到栈底的顺序),因为只有递增的时候,加入一个元素i,才知道栈顶元素在数组中右面第一个比栈顶元素大的元素是i。
|
||||||
|
|
||||||
|
文字描述理解起来有点费劲,接下来我画了一系列的图,来讲解单调栈的工作过程。
|
||||||
|
|
||||||
|
使用单调栈主要有三个判断条件。
|
||||||
|
|
||||||
|
* 当前遍历的元素T[i]小于栈顶元素T[st.top()]的情况
|
||||||
|
* 当前遍历的元素T[i]等于栈顶元素T[st.top()]的情况
|
||||||
|
* 当前遍历的元素T[i]大于栈顶元素T[st.top()]的情况
|
||||||
|
|
||||||
|
**把这三种情况分析清楚了,也就理解透彻了**。
|
||||||
|
|
||||||
|
接下来我们用temperatures = [73, 74, 75, 71, 71, 72, 76, 73]为例来逐步分析,输出应该是 [1, 1, 4, 2, 1, 1, 0, 0]。
|
||||||
|
|
||||||
|
首先先将第一个遍历元素加入单调栈
|
||||||
|

|
||||||
|
|
||||||
|
加入T[1] = 74,因为T[1] > T[0](当前遍历的元素T[i]大于栈顶元素T[st.top()]的情况),而我们要保持一个递增单调栈(从栈头到栈底),所以将T[0]弹出,T[1]加入,此时result数组可以记录了,result[0] = 1,即T[0]右面第一个比T[0]大的元素是T[1]。
|
||||||
|

|
||||||
|
|
||||||
|
加入T[2],同理,T[1]弹出
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
加入T[3],T[3] < T[2] (当前遍历的元素T[i]小于栈顶元素T[st.top()]的情况),加T[3]加入单调栈。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
加入T[4],T[4] == T[3] (当前遍历的元素T[i]等于栈顶元素T[st.top()]的情况),此时依然要加入栈,不用计算距离,因为我们要求的是右面第一个大于本元素的位置,而不是大于等于!
|
||||||
|

|
||||||
|
|
||||||
|
加入T[5],T[5] > T[4] (当前遍历的元素T[i]大于栈顶元素T[st.top()]的情况),将T[4]弹出,同时计算距离,更新result
|
||||||
|

|
||||||
|
|
||||||
|
T[4]弹出之后, T[5] > T[3] (当前遍历的元素T[i]大于栈顶元素T[st.top()]的情况),将T[3]继续弹出,同时计算距离,更新result
|
||||||
|

|
||||||
|
|
||||||
|
直到发现T[5]小于T[st.top()],终止弹出,将T[5]加入单调栈
|
||||||
|

|
||||||
|
|
||||||
|
加入T[6],同理,需要将栈里的T[5],T[2]弹出
|
||||||
|

|
||||||
|
|
||||||
|
同理,继续弹出
|
||||||
|

|
||||||
|
|
||||||
|
此时栈里只剩下了T[6]
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
加入T[7], T[7] < T[6] 直接入栈,这就是最后的情况,result数组也更新完了。
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
此时有同学可能就疑惑了,那result[6] , result[7]怎么没更新啊,元素也一直在栈里。
|
||||||
|
|
||||||
|
其实定义result数组的时候,就应该直接初始化为0,如果result没有更新,说明这个元素右面没有更大的了,也就是为0。
|
||||||
|
|
||||||
|
以上在图解的时候,已经把,这三种情况都做了详细的分析。
|
||||||
|
|
||||||
|
* 情况一:当前遍历的元素T[i]小于栈顶元素T[st.top()]的情况
|
||||||
|
* 情况二:当前遍历的元素T[i]等于栈顶元素T[st.top()]的情况
|
||||||
|
* 情况三:当前遍历的元素T[i]大于栈顶元素T[st.top()]的情况
|
||||||
|
|
||||||
|
C++代码如下:
|
||||||
|
|
||||||
|
```C++
|
||||||
|
// 版本一
|
||||||
|
class Solution {
|
||||||
|
public:
|
||||||
|
vector<int> dailyTemperatures(vector<int>& T) {
|
||||||
|
// 递减栈
|
||||||
|
stack<int> st;
|
||||||
|
vector<int> result(T.size(), 0);
|
||||||
|
st.push(0);
|
||||||
|
for (int i = 1; i < T.size(); i++) {
|
||||||
|
if (T[i] < T[st.top()]) { // 情况一
|
||||||
|
st.push(i);
|
||||||
|
} else if (T[i] == T[st.top()]) { // 情况二
|
||||||
|
st.push(i);
|
||||||
|
} else {
|
||||||
|
while (!st.empty() && T[i] > T[st.top()]) { // 情况三
|
||||||
|
result[st.top()] = i - st.top();
|
||||||
|
st.pop();
|
||||||
|
}
|
||||||
|
st.push(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
**建议一开始 都把每种情况分析好,不要上来看简短的代码,关键逻辑都被隐藏了**。
|
||||||
|
|
||||||
|
精简代码如下:
|
||||||
|
|
||||||
|
```C++
|
||||||
|
// 版本二
|
||||||
|
class Solution {
|
||||||
|
public:
|
||||||
|
vector<int> dailyTemperatures(vector<int>& T) {
|
||||||
|
stack<int> st; // 递减栈
|
||||||
|
vector<int> result(T.size(), 0);
|
||||||
|
st.push(0);
|
||||||
|
for (int i = 1; i < T.size(); i++) {
|
||||||
|
while (!st.empty() && T[i] > T[st.top()]) { // 注意栈不能为空
|
||||||
|
result[st.top()] = i - st.top();
|
||||||
|
st.pop();
|
||||||
|
}
|
||||||
|
st.push(i);
|
||||||
|
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
* 时间复杂度:O(n)
|
||||||
|
* 空间复杂度:O(n)
|
||||||
|
|
||||||
|
精简的代码是直接把情况一二三都合并到了一起,其实这种代码精简是精简,但思路不是很清晰。
|
||||||
|
|
||||||
|
建议大家把情况一二三想清楚了,先写出版本一的代码,然后在其基础上在做精简!
|
||||||
|
|
||||||
|
|
||||||
|
## 其他语言版本
|
||||||
|
|
||||||
|
|
||||||
|
Java:
|
||||||
|
|
||||||
|
Python:
|
||||||
|
|
||||||
|
Go:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------
|
||||||
|
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||||
|
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||||
|
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||||
|
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||||
|
|
@ -93,7 +93,18 @@ Java:
|
|||||||
```
|
```
|
||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
```python
|
||||||
|
class Solution:
|
||||||
|
def maxUncrossedLines(self, A: List[int], B: List[int]) -> int:
|
||||||
|
dp = [[0] * (len(B)+1) for _ in range(len(A)+1)]
|
||||||
|
for i in range(1, len(A)+1):
|
||||||
|
for j in range(1, len(B)+1):
|
||||||
|
if A[i-1] == B[j-1]:
|
||||||
|
dp[i][j] = dp[i-1][j-1] + 1
|
||||||
|
else:
|
||||||
|
dp[i][j] = max(dp[i-1][j], dp[i][j-1])
|
||||||
|
return dp[-1][-1]
|
||||||
|
```
|
||||||
|
|
||||||
Go:
|
Go:
|
||||||
|
|
||||||
|
@ -9,11 +9,10 @@
|
|||||||
|
|
||||||
> 哈希表总结篇如约而至
|
> 哈希表总结篇如约而至
|
||||||
|
|
||||||
哈希表系列也是早期讲解的时候没有写总结篇,所以选个周末给补上,毕竟「代码随想录」的系列怎么能没有总结篇呢[机智]。
|
|
||||||
|
|
||||||
# 哈希表理论基础
|
# 哈希表理论基础
|
||||||
|
|
||||||
在[关于哈希表,你该了解这些!](https://mp.weixin.qq.com/s/g8N6WmoQmsCUw3_BaWxHZA)中,我们介绍了哈希表的基础理论知识,不同于枯燥的讲解,这里介绍了都是对刷题有帮助的理论知识点。
|
在[关于哈希表,你该了解这些!](https://mp.weixin.qq.com/s/RSUANESA_tkhKhYe3ZR8Jg)中,我们介绍了哈希表的基础理论知识,不同于枯燥的讲解,这里介绍了都是对刷题有帮助的理论知识点。
|
||||||
|
|
||||||
**一般来说哈希表都是用来快速判断一个元素是否出现集合里**。
|
**一般来说哈希表都是用来快速判断一个元素是否出现集合里**。
|
||||||
|
|
||||||
@ -29,7 +28,7 @@
|
|||||||
* set(集合)
|
* set(集合)
|
||||||
* map(映射)
|
* map(映射)
|
||||||
|
|
||||||
在C++语言中,set 和 map 都分别提供了三种数据结构,每种数据结构的底层实现和用途都有所不同,在[关于哈希表,你该了解这些!](https://mp.weixin.qq.com/s/g8N6WmoQmsCUw3_BaWxHZA)中我给出了详细分析,这一知识点很重要!
|
在C++语言中,set 和 map 都分别提供了三种数据结构,每种数据结构的底层实现和用途都有所不同,在[关于哈希表,你该了解这些!](https://mp.weixin.qq.com/s/RSUANESA_tkhKhYe3ZR8Jg)中我给出了详细分析,这一知识点很重要!
|
||||||
|
|
||||||
例如什么时候用std::set,什么时候用std::multiset,什么时候用std::unordered_set,都是很有考究的。
|
例如什么时候用std::set,什么时候用std::multiset,什么时候用std::unordered_set,都是很有考究的。
|
||||||
|
|
||||||
@ -41,13 +40,13 @@
|
|||||||
|
|
||||||
一些应用场景就是为数组量身定做的。
|
一些应用场景就是为数组量身定做的。
|
||||||
|
|
||||||
在[哈希表:有效的字母异位词](https://mp.weixin.qq.com/s/vM6OszkM6L1Mx2Ralm9Dig)中,我们提到了数组就是简单的哈希表,但是数组的大小是受限的!
|
在[242.有效的字母异位词](https://mp.weixin.qq.com/s/ffS8jaVFNUWyfn_8T31IdA)中,我们提到了数组就是简单的哈希表,但是数组的大小是受限的!
|
||||||
|
|
||||||
这道题目包含小写字母,那么使用数组来做哈希最合适不过。
|
这道题目包含小写字母,那么使用数组来做哈希最合适不过。
|
||||||
|
|
||||||
在[哈希表:赎金信](https://mp.weixin.qq.com/s/sYZIR4dFBrw_lr3eJJnteQ)中同样要求只有小写字母,那么就给我们浓浓的暗示,用数组!
|
在[383.赎金信](https://mp.weixin.qq.com/s/qAXqv--UERmiJNNpuphOUQ)中同样要求只有小写字母,那么就给我们浓浓的暗示,用数组!
|
||||||
|
|
||||||
本题和[哈希表:有效的字母异位词](https://mp.weixin.qq.com/s/vM6OszkM6L1Mx2Ralm9Dig)很像,[哈希表:有效的字母异位词](https://mp.weixin.qq.com/s/vM6OszkM6L1Mx2Ralm9Dig)是求 字符串a 和 字符串b 是否可以相互组成,在[哈希表:赎金信](https://mp.weixin.qq.com/s/sYZIR4dFBrw_lr3eJJnteQ)中是求字符串a能否组成字符串b,而不用管字符串b 能不能组成字符串a。
|
本题和[242.有效的字母异位词](https://mp.weixin.qq.com/s/ffS8jaVFNUWyfn_8T31IdA)很像,[242.有效的字母异位词](https://mp.weixin.qq.com/s/ffS8jaVFNUWyfn_8T31IdA)是求 字符串a 和 字符串b 是否可以相互组成,在[383.赎金信](https://mp.weixin.qq.com/s/qAXqv--UERmiJNNpuphOUQ)中是求字符串a能否组成字符串b,而不用管字符串b 能不能组成字符串a。
|
||||||
|
|
||||||
一些同学可能想,用数组干啥,都用map不就完事了。
|
一些同学可能想,用数组干啥,都用map不就完事了。
|
||||||
|
|
||||||
@ -56,7 +55,7 @@
|
|||||||
|
|
||||||
## set作为哈希表
|
## set作为哈希表
|
||||||
|
|
||||||
在[哈希表:两个数组的交集](https://mp.weixin.qq.com/s/N9iqAchXreSVW7zXUS4BVA)中我们给出了什么时候用数组就不行了,需要用set。
|
在[349. 两个数组的交集](https://mp.weixin.qq.com/s/aMSA5zrp3jJcLjuSB0Es2Q)中我们给出了什么时候用数组就不行了,需要用set。
|
||||||
|
|
||||||
这道题目没有限制数值的大小,就无法使用数组来做哈希表了。
|
这道题目没有限制数值的大小,就无法使用数组来做哈希表了。
|
||||||
|
|
||||||
@ -67,7 +66,7 @@
|
|||||||
|
|
||||||
所以此时一样的做映射的话,就可以使用set了。
|
所以此时一样的做映射的话,就可以使用set了。
|
||||||
|
|
||||||
关于set,C++ 给提供了如下三种可用的数据结构:(详情请看[关于哈希表,你该了解这些!](https://mp.weixin.qq.com/s/g8N6WmoQmsCUw3_BaWxHZA))
|
关于set,C++ 给提供了如下三种可用的数据结构:(详情请看[关于哈希表,你该了解这些!](https://mp.weixin.qq.com/s/RSUANESA_tkhKhYe3ZR8Jg))
|
||||||
|
|
||||||
* std::set
|
* std::set
|
||||||
* std::multiset
|
* std::multiset
|
||||||
@ -75,12 +74,12 @@
|
|||||||
|
|
||||||
std::set和std::multiset底层实现都是红黑树,std::unordered_set的底层实现是哈希, 使用unordered_set 读写效率是最高的,本题并不需要对数据进行排序,而且还不要让数据重复,所以选择unordered_set。
|
std::set和std::multiset底层实现都是红黑树,std::unordered_set的底层实现是哈希, 使用unordered_set 读写效率是最高的,本题并不需要对数据进行排序,而且还不要让数据重复,所以选择unordered_set。
|
||||||
|
|
||||||
在[哈希表:快乐数](https://mp.weixin.qq.com/s/G4Q2Zfpfe706gLK7HpZHpA)中,我们再次使用了unordered_set来判断一个数是否重复出现过。
|
在[202.快乐数](https://mp.weixin.qq.com/s/n5q0ujxxrjQS3xuh3dgqBQ)中,我们再次使用了unordered_set来判断一个数是否重复出现过。
|
||||||
|
|
||||||
|
|
||||||
## map作为哈希表
|
## map作为哈希表
|
||||||
|
|
||||||
在[哈希表:两数之和](https://mp.weixin.qq.com/s/uVAtjOHSeqymV8FeQbliJQ)中map正式登场。
|
在[1.两数之和](https://mp.weixin.qq.com/s/vaMsLnH-f7_9nEK4Cuu3KQ)中map正式登场。
|
||||||
|
|
||||||
来说一说:使用数组和set来做哈希法的局限。
|
来说一说:使用数组和set来做哈希法的局限。
|
||||||
|
|
||||||
@ -89,7 +88,7 @@ std::set和std::multiset底层实现都是红黑树,std::unordered_set的底
|
|||||||
|
|
||||||
map是一种`<key, value>`的结构,本题可以用key保存数值,用value在保存数值所在的下表。所以使用map最为合适。
|
map是一种`<key, value>`的结构,本题可以用key保存数值,用value在保存数值所在的下表。所以使用map最为合适。
|
||||||
|
|
||||||
C++提供如下三种map::(详情请看[关于哈希表,你该了解这些!](https://mp.weixin.qq.com/s/g8N6WmoQmsCUw3_BaWxHZA))
|
C++提供如下三种map::(详情请看[关于哈希表,你该了解这些!](https://mp.weixin.qq.com/s/RSUANESA_tkhKhYe3ZR8Jg))
|
||||||
|
|
||||||
* std::map
|
* std::map
|
||||||
* std::multimap
|
* std::multimap
|
||||||
@ -97,21 +96,21 @@ C++提供如下三种map::(详情请看[关于哈希表,你该了解这
|
|||||||
|
|
||||||
std::unordered_map 底层实现为哈希,std::map 和std::multimap 的底层实现是红黑树。
|
std::unordered_map 底层实现为哈希,std::map 和std::multimap 的底层实现是红黑树。
|
||||||
|
|
||||||
同理,std::map 和std::multimap 的key也是有序的(这个问题也经常作为面试题,考察对语言容器底层的理解),[哈希表:两数之和](https://mp.weixin.qq.com/s/uVAtjOHSeqymV8FeQbliJQ)中并不需要key有序,选择std::unordered_map 效率更高!
|
同理,std::map 和std::multimap 的key也是有序的(这个问题也经常作为面试题,考察对语言容器底层的理解),[1.两数之和](https://mp.weixin.qq.com/s/vaMsLnH-f7_9nEK4Cuu3KQ)中并不需要key有序,选择std::unordered_map 效率更高!
|
||||||
|
|
||||||
在[哈希表:四数相加II](https://mp.weixin.qq.com/s/Ue8pKKU5hw_m-jPgwlHcbA)中我们提到了其实需要哈希的地方都能找到map的身影。
|
在[454.四数相加](https://mp.weixin.qq.com/s/12g_w6RzHuEpFts1pT6BWw)中我们提到了其实需要哈希的地方都能找到map的身影。
|
||||||
|
|
||||||
本题咋眼一看好像和[18. 四数之](https://mp.weixin.qq.com/s/r5cgZFu0tv4grBAexdcd8A),[15.三数之和](https://mp.weixin.qq.com/s/nQrcco8AZJV1pAOVjeIU_g)差不多,其实差很多!
|
本题咋眼一看好像和[18. 四数之和](https://mp.weixin.qq.com/s/SBU3THi1Kv6Sar7htqCB2Q),[15.三数之和](https://mp.weixin.qq.com/s/QfTNEByq1YlNSXRKEumwHg)差不多,其实差很多!
|
||||||
|
|
||||||
**关键差别是本题为四个独立的数组,只要找到A[i] + B[j] + C[k] + D[l] = 0就可以,不用考虑重复问题,而[18. 四数之和](https://mp.weixin.qq.com/s/nQrcco8AZJV1pAOVjeIU_g),[15.三数之和](https://mp.weixin.qq.com/s/r5cgZFu0tv4grBAexdcd8A)是一个数组(集合)里找到和为0的组合,可就难很多了!**
|
**关键差别是本题为四个独立的数组,只要找到A[i] + B[j] + C[k] + D[l] = 0就可以,不用考虑重复问题,而[18. 四数之和](https://mp.weixin.qq.com/s/SBU3THi1Kv6Sar7htqCB2Q),[15.三数之和](https://mp.weixin.qq.com/s/QfTNEByq1YlNSXRKEumwHg)是一个数组(集合)里找到和为0的组合,可就难很多了!**
|
||||||
|
|
||||||
用哈希法解决了两数之和,很多同学会感觉用哈希法也可以解决三数之和,四数之和。
|
用哈希法解决了两数之和,很多同学会感觉用哈希法也可以解决三数之和,四数之和。
|
||||||
|
|
||||||
其实是可以解决,但是非常麻烦,需要去重导致代码效率很低。
|
其实是可以解决,但是非常麻烦,需要去重导致代码效率很低。
|
||||||
|
|
||||||
在[哈希表:解决了两数之和,那么能解决三数之和么?](https://mp.weixin.qq.com/s/r5cgZFu0tv4grBAexdcd8A)中我给出了哈希法和双指针两个解法,大家就可以体会到,使用哈希法还是比较麻烦的。
|
在[15.三数之和](https://mp.weixin.qq.com/s/QfTNEByq1YlNSXRKEumwHg)中我给出了哈希法和双指针两个解法,大家就可以体会到,使用哈希法还是比较麻烦的。
|
||||||
|
|
||||||
所以[18. 四数之](https://mp.weixin.qq.com/s/r5cgZFu0tv4grBAexdcd8A),[15.三数之和](https://mp.weixin.qq.com/s/nQrcco8AZJV1pAOVjeIU_g)都推荐使用双指针法!
|
所以18. 四数之和,15.三数之和都推荐使用双指针法!
|
||||||
|
|
||||||
# 总结
|
# 总结
|
||||||
|
|
||||||
@ -127,19 +126,6 @@ std::unordered_map 底层实现为哈希,std::map 和std::multimap 的底层
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 其他语言版本
|
|
||||||
|
|
||||||
|
|
||||||
Java:
|
|
||||||
|
|
||||||
|
|
||||||
Python:
|
|
||||||
|
|
||||||
|
|
||||||
Go:
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-----------------------
|
-----------------------
|
||||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||||
|
@ -265,9 +265,46 @@ int main() {
|
|||||||
|
|
||||||
## 其他语言版本
|
## 其他语言版本
|
||||||
|
|
||||||
|
|
||||||
Java:
|
Java:
|
||||||
|
|
||||||
|
```java
|
||||||
|
public static void main(String[] args) {
|
||||||
|
int[] weight = {1, 3, 4};
|
||||||
|
int[] value = {15, 20, 30};
|
||||||
|
int bagSize = 4;
|
||||||
|
testWeightBagProblem(weight, value, bagSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void testWeightBagProblem(int[] weight, int[] value, int bagSize){
|
||||||
|
int wLen = weight.length, value0 = 0;
|
||||||
|
//定义dp数组:dp[i][j]表示背包容量为j时,前i个物品能获得的最大价值
|
||||||
|
int[][] dp = new int[wLen + 1][bagSize + 1];
|
||||||
|
//初始化:背包容量为0时,能获得的价值都为0
|
||||||
|
for (int i = 0; i <= wLen; i++){
|
||||||
|
dp[i][0] = value0;
|
||||||
|
}
|
||||||
|
//遍历顺序:先遍历物品,再遍历背包容量
|
||||||
|
for (int i = 1; i <= wLen; i++){
|
||||||
|
for (int j = 1; j <= bagSize; j++){
|
||||||
|
if (j < weight[i - 1]){
|
||||||
|
dp[i][j] = dp[i - 1][j];
|
||||||
|
}else{
|
||||||
|
dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - weight[i - 1]] + value[i - 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//打印dp数组
|
||||||
|
for (int i = 0; i <= wLen; i++){
|
||||||
|
for (int j = 0; j <= bagSize; j++){
|
||||||
|
System.out.print(dp[i][j] + " ");
|
||||||
|
}
|
||||||
|
System.out.print("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
|
||||||
|
@ -211,9 +211,35 @@ int main() {
|
|||||||
|
|
||||||
## 其他语言版本
|
## 其他语言版本
|
||||||
|
|
||||||
|
|
||||||
Java:
|
Java:
|
||||||
|
|
||||||
|
```java
|
||||||
|
public static void main(String[] args) {
|
||||||
|
int[] weight = {1, 3, 4};
|
||||||
|
int[] value = {15, 20, 30};
|
||||||
|
int bagWight = 4;
|
||||||
|
testWeightBagProblem(weight, value, bagWight);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void testWeightBagProblem(int[] weight, int[] value, int bagWeight){
|
||||||
|
int wLen = weight.length;
|
||||||
|
//定义dp数组:dp[j]表示背包容量为j时,能获得的最大价值
|
||||||
|
int[] dp = new int[bagWeight + 1];
|
||||||
|
//遍历顺序:先遍历物品,再遍历背包容量
|
||||||
|
for (int i = 0; i < wLen; i++){
|
||||||
|
for (int j = bagWeight; j >= weight[i]; j--){
|
||||||
|
dp[j] = Math.max(dp[j], dp[j - weight[i]] + value[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//打印dp数组
|
||||||
|
for (int j = 0; j <= bagWeight; j++){
|
||||||
|
System.out.print(dp[j] + " ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user