Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

714. 买卖股票的最佳时机含手续费 #83

Open
yankewei opened this issue Dec 17, 2020 · 1 comment
Open

714. 买卖股票的最佳时机含手续费 #83

yankewei opened this issue Dec 17, 2020 · 1 comment
Labels
中等 题目难度为中等 动态规划 题目包含动态规划解法 数组 题目类型为数组 贪心算法 题目包含贪心解法

Comments

@yankewei
Copy link
Owner

yankewei commented Dec 17, 2020

给定一个整数数组 prices,其中第 i 个元素代表了第 i 天的股票价格 ;非负整数 fee 代表了交易股票的手续费用。

你可以无限次地完成交易,但是你每笔交易都需要付手续费。如果你已经购买了一个股票,在卖出它之前你就不能再继续购买股票了。

返回获得利润的最大值。

注意: 这里的一笔交易指买入持有并卖出股票的整个过程,每笔交易你只需要为支付一次手续费。

示例 1:

输入: prices = [1, 3, 2, 8, 4, 9], fee = 2
输出: 8
解释: 能够达到的最大利润:  
在此处买入 prices[0] = 1
在此处卖出 prices[3] = 8
在此处买入 prices[4] = 4
在此处卖出 prices[5] = 9
总利润: ((8 - 1) - 2) + ((9 - 4) - 2) = 8.

注意:

  • 0 < prices.length <= 50000.
  • 0 < prices[i] < 50000.
  • 0 <= fee < 50000.

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

@yankewei yankewei added 动态规划 题目包含动态规划解法 数组 题目类型为数组 贪心算法 题目包含贪心解法 中等 题目难度为中等 labels Dec 17, 2020
@yankewei
Copy link
Owner Author

DP大法

说到动态规划,那我们先来定义状态转移方程把,在第 i 天,你要么手上持有股票,要么手上没有股票,所以我们用dp[i][0]来表示第 i 天,手上没有股票的时候最大收益,用dp[i][1]表示第 i 天,手上有股票的时候最大收益。下面来对这两种情况进行分析:

  • dp[i][0]
    • 今天把股票卖了,那么今天的收益应该是,昨天拥有股票时的收益 + 今天股票的价格 - 手续费,用方程来表示dp[i-1] + prices[i] - fee
    • 今天没有任何操作,那么今天的收益应该是,昨天没有股票的收益,用方程来表示dp[i-1][0]
    • 所以最大收益就是上边两种情况的最大值,方程表示dp[i][0] = max(dp[i-1] + prices[i] - fee, dp[i-1][0])
  • dp[i][1]
    • 今天买了股票,那么今天的收益应该是,昨天没有股票时的收益 - 今天股票的价格,用方程表示dp[i-1][0] - prices[i]
    • 今天没有任何操作,那么今天的收益应该是,昨天拥有股票时的收益,用方程来表示dp[i-1][1]
    • 所以最大收益就是上边两种情况的最大值,方程表示dp[i][1] = max(dp[i-1][0] - prices[i], dp[i-1][1])

有了转移方程,来定义初始方程,就是第0天的两种情况

  • dp[0][0] = 0 // 表示第0天没有买股票
  • dp[0][1] = -prices[0] // 表示第0天买了股票
func maxProfit(prices []int, fee int) int {
    if len(prices) < 2 {
        return 0
    }

    dp := [][2]int{{0,-prices[0]}}

    for i := 1; i < len(prices); i++ {
        profit0 := max(dp[i-1][1] + prices[i] - fee, dp[i-1][0])
        profit1 := max(dp[i-1][0] - prices[i], dp[i-1][1])
        dp = append(dp, [2]int{profit0, profit1})
    }

    return dp[len(prices)-1][0]
}

func max(x, y int) int {
    if x > y {
        return x
    }
    return y
}

然后我们发现第 i 天的收益只和第 i-1 天的收益有关系,所以可以优化空间

func maxProfit(prices []int, fee int) int {
    if len(prices) < 2 {
        return 0
    }

    dp := [2]int{0, -prices[0]}
    for i := 1; i < len(prices); i++ {
        temp := max(dp[1] + prices[i] - fee, dp[0])
        dp[1] = max(dp[0]- prices[i], dp[1])
        dp[0] = temp
    }

    return dp[0]
}

func max(x, y int) int {
    if x > y {
        return x
    }
    return y
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
中等 题目难度为中等 动态规划 题目包含动态规划解法 数组 题目类型为数组 贪心算法 题目包含贪心解法
Projects
None yet
Development

No branches or pull requests

1 participant