← 返回编程题库
coding-best-single-trade-in-a-day简单免费版2000ms未尝试

日内最优单次交易

Best Single Trade in a Day

开始编码

日内策略组拿到一支股票当天的逐分钟收盘价序列 prices(按时间升序),希望复盘当天事后看「单次最佳交易」能赚多少:在某个时刻 i 买入一股,再在之后某个时刻 j > i 卖出一股,收益是 prices[j] - prices[i]。我们要找的是所有合法 (i, j) 组合下的最大收益——这是一个事后基准,用来评估当日实际策略离「上帝视角的最优单笔交易」有多远。

请实现 solution(prices: list[float]) -> float。规则:(1)必须先买后卖,i < j 严格成立;(2)允许「不交易」——如果当日价格一路下跌,所有合法 (i, j) 的收益都是负的,那最优选择是不入场,应返回 0.0;(3)当 len(prices) < 2 时同样无法成交,返回 0.0

示例solution([7.0, 1.0, 5.0, 3.0, 6.0, 4.0]) 应返回 5.0。在 i = 1 买入(价 1.0),在 j = 4 卖出(价 6.0),收益 6.0 - 1.0 = 5.0。注意不能选 i = 0 买(价 7.0),因为那样后续最高也只能在 j = 4 卖到 6.0,收益 -1.0;事后看,应该等到 i = 1 的低点再入场。再看 solution([8.0, 6.0, 4.0, 2.0]):价格单调下跌,任何先买后卖都会亏损,最优选择是不交易,返回 0.0

朴素的 O(n²) 双重循环在 n = 10⁵ 时会超时。关键观察是:固定卖出时刻 j 后,最优买入时刻一定是 prices[0..j-1] 里的最小值。所以一遍扫描即可——同时维护「到目前为止的最小价」和「到目前为止的最大收益」,每一步用当前价减去历史最小价更新最大收益。整体 O(n) 时间、O(1) 额外空间。这是动态规划在最简单情形下的退化形态:状态只需要常数个标量。

约束条件

  • 0 ≤ len(prices) ≤ 100000
  • 0 < prices[i] ≤ 10⁶(正实数报价)
  • 买入与卖出必须满足 i < j(同一时刻不能既买又卖)
  • 若没有任何 (i, j) 能产生正收益,或 len(prices) < 2,返回 0.0(表示「不交易」)
  • 返回值允许 1e-6 的浮点误差

样例

Case 1 · classic dip-then-peak

输入: [[7,1,5,3,6,4]]

期望: 5

在 i=1 买入(价 1.0),在 j=4 卖出(价 6.0),收益 5.0。如果在 i=0(价 7.0)入场,后续最高 6.0 反而亏 1.0;事后看应等到 1.0 的低点再买。

Case 2 · monotonically decreasing — do not trade

输入: [[8,6,4,2]]

期望: 0

价格一路下跌,任何「先买后卖」组合的收益都是负的。规则允许「不交易」,所以最优收益是 0.0,而不是最小负数。

最近提交

还没有提交记录。

编码区

实现 solution(...)。本地运行当前支持 Python 可见样例;服务端提交会运行可见样例和隐藏测试。

加载编辑器...
计时0:00

默认展示公开样例。点击「运行样例」后会在这里显示实际输出;点击「提交评测」会进入隐藏测试。

Case 1 · classic dip-then-peak

输入: [[7,1,5,3,6,4]]

期望: 5

在 i=1 买入(价 1.0),在 j=4 卖出(价 6.0),收益 5.0。如果在 i=0(价 7.0)入场,后续最高 6.0 反而亏 1.0;事后看应等到 1.0 的低点再买。

Case 2 · monotonically decreasing — do not trade

输入: [[8,6,4,2]]

期望: 0

价格一路下跌,任何「先买后卖」组合的收益都是负的。规则允许「不交易」,所以最优收益是 0.0,而不是最小负数。