初级算法练习第十四节

108 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第28天,点击查看活动详情

1. 引言

接下来继续下一题开展对应leetcode 习题课中初级算法题目的练习,这个就当我的学习笔记了,大家一起交流,让我们一起学习变得更好吧! 官网地址:leetcode.cn/leetbook/re…

2. 题型

1.买卖股票的最佳时机 给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。

你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。

返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。

示例1:
输入:[7,1,5,3,6,4]
输出:5
解释:在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
     注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。


示例2:
输入:prices = [7,6,4,3,1]
输出:0
解释:在这种情况下, 没有交易完成, 所以最大利润为 0。

提示: 1 <= prices.length <= 105 0 <= prices[i] <= 104

思路:

思路及算法

限定交易次数 k=1

状态转移方程:首先我们需要确认的事:该题要求我们最小值时候买入,最高值抛出,最小值买入时间永远在最高值卖出时间之前,所以我们定义第i天不持有 由 第i-1天不持有然后不操作 和 第i-1天持有然后卖出 两种情况的最大值转移过来 dp[i][1][0] = Math.max(dp[i - 1][1][0], dp[i - 1][1][1] + prices[i]) 当我们第i天持有 由 第i-1天持有然后不操作 和 第i-1天不持有然后买入 两种情况的最大值转移过来 dp[i][1][1] = Math.max(dp[i - 1][1][1], dp[i - 1][0][0] - prices[i]) = Math.max(dp[i - 1][1][1], -prices[i]) 当我们k=0时 没有交易次数,dp[i - 1][0][0] 为 0 ,其次k是固定值1,不影响结果,所以可以不用管,简化之后如下

dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]) dp[i][1] = Math.max(dp[i - 1][1], -prices[i])

解答:

//时间复杂度O(n) 空间复杂度O(n),dp数组第二维是常数
const maxProfit = function (prices) {
    let n = prices.length;
    let dp = Array.from(new Array(n), () => new Array(2));
    dp[0][0] = 0; //第0天不持有
    dp[0][1] = -prices[0]; //第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], -prices[i]);
    }
    return dp[n - 1][0];
};