Loading

[LeetCode] 121. Best Time to Buy and Sell Stock(买卖股票的最佳时机)

Description

Say you have an array for which the ith element is the price of a given stock on day i.

你有一个数组,数组的第 i 个元素表示第 i 天某只股票的售价。

If you were only permitted to complete at most one transaction (i.e., buy one and sell one share of the stock), desgin an algorithm to find the maximum profit.

如果只允许你进行一次交易(买一股,卖一股),设计一个算法,求获利的最大值。

Note that you cannot sell a stock before you buy one.

注意你必须把当前持有的股票卖出后才可再买入。

Examples

Example 1

Input: [7,1,5,3,6,4]
Output: 5
Explanation: Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 6-1 = 5.
             Not 7-1 = 6, as selling price needs to be larger than buying price.

Example 2

Input: [7,6,4,3,1]
Output: 0
Explanation: In this case, no transaction is done, i.e. max profit = 0.

Solution

这题印象中是动态规划的一道例题,但很不幸的是我把这部分知识忘了,遂翻看 Discussion。

这题更直接的一个问法是所谓最大子数组问题(给定一个数组(当然,其中包含负数),求解这个数组的一个子数组,使子数组的和最大),我们把上面的问题中的股票售价换成股票售价与前一天售价的差值,就是这个最大子数组问题了。

对于最大子数组问题,思路如下:

假设有数组 nums,我们需要求以下标 i 结尾的子数组的最大值,那么有以下两种情况:

  1. 包括下标 i 之前的元素,这样只要求以 i - 1 下标为结尾的子数组的最大值,加上 i 即可

  2. 不包括下标 i 之前的元素,即单纯只有 nums[i](因为之前元素的子数组和的最大值可能为负数)

以上两种情况取最大值,得到状态转移方程:

\[result[i] = \max(result[i - 1] + nums[i], nums[i]) \]

由于当前状态只与前一个状态有关,所以本来需要开一个数组的空间,现在可以压缩到一个变量

localMax = max(nums[i], localMax + nums[i])

参照上面的例子,得出下面的最后代码:

import kotlin.math.max

class Solution {
    fun maxProfit(prices: IntArray): Int {
        if (prices.size < 2) {
            return 0
        }
        
        var result = 0
        var currentMax = 0
        
        for (i in 1..prices.lastIndex) {
            currentMax += prices[i] - prices[i - 1]
            currentMax = max(0, currentMax)
            result = max(currentMax, result)
        }
        
        return result
    }
}
posted @ 2020-10-13 20:41  Zhongju.copy()  阅读(97)  评论(0编辑  收藏  举报