买卖股票的最佳时机
将每个元素之间的差值算出来,形成一个数组,这道题就演变成了求最大子序之和。
暴力
双循环求得最大差值,不过超时了。
function maxProfit(prices: number[]): number {
let max = 0
for (let i = 0; i < prices.length - 1; i++) {
for (let j = i + 1; j < prices.length; j++) {
max = Math.max(prices[j] - prices[i], max)
}
}
return max
}
单循环
想要最高收益,在历史最低价买入即可。
function maxProfit(prices: number[]): number {
let max = 0
let min = prices[0]
for (let i = 0; i < prices.length; i++) {
max = Math.max(prices[i] - min, max)
min = Math.min(prices[i], min)
}
return max
}
动态规划
相对于最大子序和,该题需要两种状态才可以确认收益:0
表示未持有股票,1
表示持有股票。 dp[0][0]
表示第 0 天持有股票,所以第一天 dp[0][0] = -prices[0]
;dp[0][1]
表示第 0 天不持有股票,所以 dp[0][1] = 0
。
function maxProfit(prices: number[]) {
const len = prices.length
const dp = Array(len).fill([0, 0])
// 边界条件
dp[0] = [-prices[0], 0]
for (let i = 1; i < len; i++) {
// 转移公式
dp[i] = [
Math.max(dp[i - 1][0], -prices[i]),
Math.max(dp[i - 1][1], dp[i - 1][0] + prices[i])
]
}
return dp[len - 1][1]
}