LeetCode 714: Best Time to Buy and Sell Stock with Transaction Fee (Two-State DP)
LeetCode 714Dynamic ProgrammingGreedyToday we solve LeetCode 714 - Best Time to Buy and Sell Stock with Transaction Fee.
Source: https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/
English
Problem Summary
You are given daily stock prices and a fixed transaction fee. You may buy/sell as many times as you want, but you can only hold one share at a time. Return the maximum profit.
Key Idea
Track two states while scanning prices:
1) hold: maximum profit when you end day i holding one stock.
2) cash: maximum profit when you end day i with no stock.
Transitions:
newHold = max(hold, cash - price)
newCash = max(cash, hold + price - fee)
We pay the transaction fee on selling.
Complexity
Time O(n), extra space O(1).
Reference Implementations (Java / Go / C++ / Python / JavaScript)
class Solution {
public int maxProfit(int[] prices, int fee) {
int hold = -prices[0];
int cash = 0;
for (int i = 1; i < prices.length; i++) {
int newHold = Math.max(hold, cash - prices[i]);
int newCash = Math.max(cash, hold + prices[i] - fee);
hold = newHold;
cash = newCash;
}
return cash;
}
}func maxProfit(prices []int, fee int) int {
hold, cash := -prices[0], 0
for i := 1; i < len(prices); i++ {
newHold := hold
if cash-prices[i] > newHold {
newHold = cash - prices[i]
}
newCash := cash
if hold+prices[i]-fee > newCash {
newCash = hold + prices[i] - fee
}
hold, cash = newHold, newCash
}
return cash
}class Solution {
public:
int maxProfit(vector<int>& prices, int fee) {
int hold = -prices[0], cash = 0;
for (int i = 1; i < (int)prices.size(); i++) {
int newHold = max(hold, cash - prices[i]);
int newCash = max(cash, hold + prices[i] - fee);
hold = newHold;
cash = newCash;
}
return cash;
}
};class Solution:
def maxProfit(self, prices: list[int], fee: int) -> int:
hold, cash = -prices[0], 0
for i in range(1, len(prices)):
new_hold = max(hold, cash - prices[i])
new_cash = max(cash, hold + prices[i] - fee)
hold, cash = new_hold, new_cash
return cashvar maxProfit = function(prices, fee) {
let hold = -prices[0], cash = 0;
for (let i = 1; i < prices.length; i++) {
const newHold = Math.max(hold, cash - prices[i]);
const newCash = Math.max(cash, hold + prices[i] - fee);
hold = newHold;
cash = newCash;
}
return cash;
};中文
题目概述
给定股票每日价格数组和固定交易手续费 fee。你可以进行多次交易,但同一时间最多持有一股。求最大利润。
核心思路
遍历价格时维护两个状态:
1)hold:当天结束时“手里持有一股”的最大利润。
2)cash:当天结束时“手里没有股票”的最大利润。
状态转移:
newHold = max(hold, cash - price)
newCash = max(cash, hold + price - fee)
手续费在卖出时扣除即可。
复杂度分析
时间复杂度 O(n),额外空间复杂度 O(1)。
参考实现(Java / Go / C++ / Python / JavaScript)
class Solution {
public int maxProfit(int[] prices, int fee) {
int hold = -prices[0];
int cash = 0;
for (int i = 1; i < prices.length; i++) {
int newHold = Math.max(hold, cash - prices[i]);
int newCash = Math.max(cash, hold + prices[i] - fee);
hold = newHold;
cash = newCash;
}
return cash;
}
}func maxProfit(prices []int, fee int) int {
hold, cash := -prices[0], 0
for i := 1; i < len(prices); i++ {
newHold := hold
if cash-prices[i] > newHold {
newHold = cash - prices[i]
}
newCash := cash
if hold+prices[i]-fee > newCash {
newCash = hold + prices[i] - fee
}
hold, cash = newHold, newCash
}
return cash
}class Solution {
public:
int maxProfit(vector<int>& prices, int fee) {
int hold = -prices[0], cash = 0;
for (int i = 1; i < (int)prices.size(); i++) {
int newHold = max(hold, cash - prices[i]);
int newCash = max(cash, hold + prices[i] - fee);
hold = newHold;
cash = newCash;
}
return cash;
}
};class Solution:
def maxProfit(self, prices: list[int], fee: int) -> int:
hold, cash = -prices[0], 0
for i in range(1, len(prices)):
new_hold = max(hold, cash - prices[i])
new_cash = max(cash, hold + prices[i] - fee)
hold, cash = new_hold, new_cash
return cashvar maxProfit = function(prices, fee) {
let hold = -prices[0], cash = 0;
for (let i = 1; i < prices.length; i++) {
const newHold = Math.max(hold, cash - prices[i]);
const newCash = Math.max(cash, hold + prices[i] - fee);
hold = newHold;
cash = newCash;
}
return cash;
};
Comments