comments | difficulty | edit_url | tags | ||
---|---|---|---|---|---|
true |
中等 |
|
给定一个整数数组prices
,其中第 prices[i]
表示第 i
天的股票价格 。
设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):
- 卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
示例 1:
输入: prices = [1,2,3,0,2] 输出: 3 解释: 对应的交易状态为: [买入, 卖出, 冷冻期, 买入, 卖出]
示例 2:
输入: prices = [1] 输出: 0
提示:
1 <= prices.length <= 5000
0 <= prices[i] <= 1000
我们设计一个函数
函数
如果
否则,我们可以选择不交易,此时
答案为
为了避免重复计算,我们使用记忆化搜索的方法,用一个数组
时间复杂度
class Solution:
def maxProfit(self, prices: List[int]) -> int:
@cache
def dfs(i: int, j: int) -> int:
if i >= len(prices):
return 0
ans = dfs(i + 1, j)
if j:
ans = max(ans, prices[i] + dfs(i + 2, 0))
else:
ans = max(ans, -prices[i] + dfs(i + 1, 1))
return ans
return dfs(0, 0)
class Solution {
private int[] prices;
private Integer[][] f;
public int maxProfit(int[] prices) {
this.prices = prices;
f = new Integer[prices.length][2];
return dfs(0, 0);
}
private int dfs(int i, int j) {
if (i >= prices.length) {
return 0;
}
if (f[i][j] != null) {
return f[i][j];
}
int ans = dfs(i + 1, j);
if (j > 0) {
ans = Math.max(ans, prices[i] + dfs(i + 2, 0));
} else {
ans = Math.max(ans, -prices[i] + dfs(i + 1, 1));
}
return f[i][j] = ans;
}
}
class Solution {
public:
int maxProfit(vector<int>& prices) {
int n = prices.size();
int f[n][2];
memset(f, -1, sizeof(f));
function<int(int, int)> dfs = [&](int i, int j) {
if (i >= n) {
return 0;
}
if (f[i][j] != -1) {
return f[i][j];
}
int ans = dfs(i + 1, j);
if (j) {
ans = max(ans, prices[i] + dfs(i + 2, 0));
} else {
ans = max(ans, -prices[i] + dfs(i + 1, 1));
}
return f[i][j] = ans;
};
return dfs(0, 0);
}
};
func maxProfit(prices []int) int {
n := len(prices)
f := make([][2]int, n)
for i := range f {
f[i] = [2]int{-1, -1}
}
var dfs func(i, j int) int
dfs = func(i, j int) int {
if i >= n {
return 0
}
if f[i][j] != -1 {
return f[i][j]
}
ans := dfs(i+1, j)
if j > 0 {
ans = max(ans, prices[i]+dfs(i+2, 0))
} else {
ans = max(ans, -prices[i]+dfs(i+1, 1))
}
f[i][j] = ans
return ans
}
return dfs(0, 0)
}
function maxProfit(prices: number[]): number {
const n = prices.length;
const f: number[][] = Array.from({ length: n }, () => Array.from({ length: 2 }, () => -1));
const dfs = (i: number, j: number): number => {
if (i >= n) {
return 0;
}
if (f[i][j] !== -1) {
return f[i][j];
}
let ans = dfs(i + 1, j);
if (j) {
ans = Math.max(ans, prices[i] + dfs(i + 2, 0));
} else {
ans = Math.max(ans, -prices[i] + dfs(i + 1, 1));
}
return (f[i][j] = ans);
};
return dfs(0, 0);
}
我们也可以用动态规划的方法求解。
我们定义
当
时间复杂度
我们注意到,状态
class Solution:
def maxProfit(self, prices: List[int]) -> int:
n = len(prices)
f = [[0] * 2 for _ in range(n)]
f[0][1] = -prices[0]
for i in range(1, n):
f[i][0] = max(f[i - 1][0], f[i - 1][1] + prices[i])
f[i][1] = max(f[i - 1][1], f[i - 2][0] - prices[i])
return f[n - 1][0]
class Solution {
public int maxProfit(int[] prices) {
int n = prices.length;
int[][] f = new int[n][2];
f[0][1] = -prices[0];
for (int i = 1; i < n; i++) {
f[i][0] = Math.max(f[i - 1][0], f[i - 1][1] + prices[i]);
f[i][1] = Math.max(f[i - 1][1], (i > 1 ? f[i - 2][0] : 0) - prices[i]);
}
return f[n - 1][0];
}
}
class Solution {
public:
int maxProfit(vector<int>& prices) {
int n = prices.size();
int f[n][2];
memset(f, 0, sizeof(f));
f[0][1] = -prices[0];
for (int i = 1; i < n; ++i) {
f[i][0] = max(f[i - 1][0], f[i - 1][1] + prices[i]);
f[i][1] = max(f[i - 1][1], (i > 1 ? f[i - 2][0] : 0) - prices[i]);
}
return f[n - 1][0];
}
};
func maxProfit(prices []int) int {
n := len(prices)
f := make([][2]int, n)
f[0][1] = -prices[0]
for i := 1; i < n; i++ {
f[i][0] = max(f[i-1][0], f[i-1][1]+prices[i])
if i > 1 {
f[i][1] = max(f[i-1][1], f[i-2][0]-prices[i])
} else {
f[i][1] = max(f[i-1][1], -prices[i])
}
}
return f[n-1][0]
}
function maxProfit(prices: number[]): number {
const n = prices.length;
const f: number[][] = Array.from({ length: n }, () => Array.from({ length: 2 }, () => 0));
f[0][1] = -prices[0];
for (let i = 1; i < n; ++i) {
f[i][0] = Math.max(f[i - 1][0], f[i - 1][1] + prices[i]);
f[i][1] = Math.max(f[i - 1][1], (i > 1 ? f[i - 2][0] : 0) - prices[i]);
}
return f[n - 1][0];
}
class Solution:
def maxProfit(self, prices: List[int]) -> int:
f, f0, f1 = 0, 0, -prices[0]
for x in prices[1:]:
f, f0, f1 = f0, max(f0, f1 + x), max(f1, f - x)
return f0
class Solution {
public int maxProfit(int[] prices) {
int f = 0, f0 = 0, f1 = -prices[0];
for (int i = 1; i < prices.length; ++i) {
int g0 = Math.max(f0, f1 + prices[i]);
f1 = Math.max(f1, f - prices[i]);
f = f0;
f0 = g0;
}
return f0;
}
}
class Solution {
public:
int maxProfit(vector<int>& prices) {
int f = 0, f0 = 0, f1 = -prices[0];
for (int i = 1; i < prices.size(); ++i) {
int g0 = max(f0, f1 + prices[i]);
f1 = max(f1, f - prices[i]);
f = f0;
f0 = g0;
}
return f0;
}
};
func maxProfit(prices []int) int {
f, f0, f1 := 0, 0, -prices[0]
for _, x := range prices[1:] {
f, f0, f1 = f0, max(f0, f1+x), max(f1, f-x)
}
return f0
}
function maxProfit(prices: number[]): number {
let [f, f0, f1] = [0, 0, -prices[0]];
for (const x of prices.slice(1)) {
[f, f0, f1] = [f0, Math.max(f0, f1 + x), Math.max(f1, f - x)];
}
return f0;
}