一句话总结:
找最大差值就像找股票最佳买入卖出时机——记录历史最低价,然后看后面哪天卖出赚最多!
一、最优解法(一次遍历)
核心思路:
- 维护一个历史最小值
minPrice - 遍历数组,计算当前价格与历史最低价的差值,更新最大利润
Kotlin 代码:
fun maxProfit(prices: IntArray): Int {
if (prices.size < 2) return 0
var maxDiff = 0
var minPrice = prices[0]
for (i in 1 until prices.size) {
if (prices[i] > minPrice) {
maxDiff = maxOf(maxDiff, prices[i] - minPrice)
} else {
minPrice = prices[i] // 更新历史最低价
}
}
return maxDiff
}
时间复杂度: O(n) (只需遍历一次数组)
空间复杂度: O(1) (仅用两个变量存储状态)
二、测试用例
fun main() {
println(maxProfit(intArrayOf(7,1,5,3,6,4))) // 输出5(6-1)
println(maxProfit(intArrayOf(5,4,3,2,1))) // 输出0(一直跌)
println(maxProfit(intArrayOf(2,4,1,7))) // 输出6(7-1)
println(maxProfit(intArrayOf(2,2,2))) // 输出0(无上涨)
println(maxProfit(intArrayOf(5))) // 输出0(单元素)
}
三、分步图解(以数组[7,1,5,3,6,4]为例)
初始化:minPrice=7, maxDiff=0
步骤1:i=1 (price=1)
1 < 7 → 更新minPrice=1
maxDiff仍为0
步骤2:i=2 (price=5)
5-1=4 > 0 → maxDiff=4
步骤3:i=3 (price=3)
3-1=2 < 4 → maxDiff保持4
步骤4:i=4 (price=6)
6-1=5 >4 → maxDiff=5
步骤5:i=5 (price=4)
4-1=3 <5 → maxDiff保持5
最终结果:5
四、常见问题
Q1:如果所有价格都下跌怎么办?
A:最大差值为0(如测试用例2)
Q2:为什么不用双重循环暴力解法?
A:时间复杂度O(n²)在数据量大时会超时
Q3:如何处理空数组或单元素数组?
A:直接返回0(代码开头已处理)
口诀:
最大差值很简单,
历史最低记心间。
后面价格若更高,
更新利润笑开颜!