SDE / AS / Intern · Coding

Amazon Coding:无限次股票交易含手续费,Cash/Hold 怎样更新?

两状态DP保留旧日状态,每次卖出扣费,避免费用重复和未平仓虚增收益。

题目重点:两状态DP保留旧日状态,每次卖出扣费,避免费用重复和未平仓虚增收益。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • 非负整数价格与手续费,最多持有一股、不可做空;买后卖为交易,费用每次卖出一次。
  • 训练每天最多一动作,允许不交易;最终必须无持仓。冷却期与交易次数上限未给,不默认加入。

解题路线

  1. cash为处理前缀后无股最高现金,hold为持一股最高账面现金。更新new_cash=max(cash,hold+price-fee),new_hold=max(hold,cash-price),两个均读取旧状态。
  2. 不交易、卖出、买入覆盖合法一天决策;cash初始0,hold不可达。代码用None避免负无穷浮点与超大整数混算溢出。
  3. 手续费放卖出或买入可选择一种约定,但不能两边都扣;若放买入,状态初值和解释必须跟着改。最后返回cash,未卖出资产不能直接算已实现收益。
  4. 只累计正相邻涨幅会在小波动里多次扣费,可能错过一次长持仓更优;两状态DP能比较多次交易与跨下跌保持仓位。
  5. 如果题目还需要统一不同次数模式,必须先核前两道正式规则,不解码谐音就宣称单次/多次原题已经全部完成。

手动走一遍

训练prices=[1,3,2,8,4,9]、fee=2,1买8卖得5,4买9卖得3,共8。价格不涨或手续费很大时结果0。

Python 参考实现

下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。

代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。

def maximum_profit(prices,fee):
    """At most one share, no shorting; fee once per sell, at most one action per day."""
    if fee < 0 or any(p < 0 for p in prices):raise ValueError("nonnegative prices and fee required")
    cash=0
    hold=None
    for price in prices:
        new_cash=max(cash,hold+price-fee) if hold is not None else cash
        new_hold=max(hold,cash-price) if hold is not None else cash-price
        cash,hold=new_cash,new_hold
    return cash

复杂度

O(n)时间、O(1)辅助状态;固定宽度需核金额范围,Python大整数的位复杂度另算。

易错点与追问

容易失分的边界

  • 每买卖各扣fee造成双扣。
  • 返回hold当最终现金。
  • 用浮点无穷参与任意大整数加减。

继续深挖

  • 有冷却一天时怎样加状态?
  • 最多两次交易怎样加次数维?
  • 需要输出买卖日怎么回溯?
✓已复制微信号!