题目:
leetcode链接:初级算法-买卖股票的最佳时机 II
说明:给你一个整数数组 prices ,其中 prices[i] 表示某支股票第i天的价格。
在每一天,你可以决定是否购买或出售股票。你在任何时候最多只能持有一股股票。你也可以先购买,然后在 同一天 出售。
返回你能获得的最大利润 。
理解:
1、prices为某股票每日股价的数组:虽然没提,但股票基本仅在工作日会有波动,虽然没什么用,但长度可以锁定为5。
2、你可以决定是否购买或出售股票:在股票数组长度反应的时间内,你可以不买,多次买入或卖出,即每日结束后手里可能有股票或者没股票。
3、你在任何时候最多只能持有一股股票:每日结束后顶多持有一只股票,即持有骨片数量为0或1。
4、你能获得的最大利润:利润为正值,根据股价,如果操作股票会出现负利润,可以不操作,此时顶多没有收益。
大致思路:
1、统计每日有股票和没股票时的收益,在最后一天持有股票的收益将小于不持有股票的收益 - 动态规划
2、统计每日可能的正向股票收益 - 贪心算法
题解:
方案一:动态规划(一)
var maxProfit = function(prices) {
const n = prices.length;
const dp = new Array(n).fill(0).map(v => new Array(2).fill(0));
dp[0][0] = 0, dp[0][1] = -prices[0];
for (let i = 1; i < n; ++i) {
dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] - prices[i]);
}
return dp[n - 1][0];
};
时间复杂度:O(n),其中 nnn 为数组的长度。一共有 2n2n2n 个状态,每次状态转移的时间复杂度为 O(1),因此时间复杂度为 O(2n)=O(n)。
空间复杂度:O(n)。我们需要开辟 O(n) 空间存储动态规划中的所有状态。如果使用空间优化,空间复杂度可以优化至 O(1)。
方案二:动态规划(二)
上面的状态转移方程中,每一天的状态只与前一天的状态有关,而与更早的状态都无关,因此我们不必存储这些无关的状态,只需要将 dp[i−1][0]和 dp[i−1][1]存放在两个变量中,通过它们计算出 dp[i][0]和 dp[i][1]并存回对应的变量,以便于第 i+1天的状态转移即可
var maxProfit = function(prices) {
const n = prices.length;
let dp0 = 0, dp1 = -prices[0];
for (let i = 1; i < n; ++i) {
let newDp0 = Math.max(dp0, dp1 + prices[i]);
let newDp1 = Math.max(dp1, dp0 - prices[i]);
dp0 = newDp0;
dp1 = newDp1;
}
return dp0;
};
方案三:贪心算法
var maxProfit = function(prices) {
let ans = 0;
let n = prices.length;
for (let i = 1; i < n; ++i) {
ans += Math.max(0, prices[i] - prices[i - 1]);
}
return ans;
};
时间复杂度:O(n)O(n)O(n),其中 nnn 为数组的长度。我们只需要遍历一次数组即可。
空间复杂度:O(1)O(1)O(1)。只需要常数空间存放若干变量。
总结:
本篇主要记录了下leetcode"买卖股票的最佳时机"算法题,采用动态规划和贪心算法下的实现,实际或许还有更多更优的解题方案,若时间允许我们可以多做尝试~