这个问题可以通过单调栈来解决,以提高效率。
问题的关键在于找到每件商品左侧第一个价格小于等于该商品的商品,从而计算总优惠金额。单调栈是解决这种“最近小于等于/大于等于”问题的理想选择。
解题思路
-
初始化单调栈:
- 单调栈存储商品的索引,保证栈内对应的价格是递增的。
-
遍历价格数组:
- 对于当前商品 p[i]p[i],如果栈不为空且栈顶商品价格 p[stack[−1]]p[stack[-1]] 大于 p[i]p[i],弹出栈顶。
- 如果栈不为空且 p[stack[−1]]≤p[i]p[stack[-1]] \leq p[i],说明栈顶商品是最近一个满足条件的优惠商品,记录其价格作为当前商品的优惠。
- 将当前商品索引压入栈。
-
计算总优惠:
- 遍历完成后,将累计的优惠值返回。
实现代码
以下是 Python 代码实现:
def solution(N: int, p: list) -> int:
# 单调栈
stack = []
total_discount = 0
for i in range(N):
# 保持单调栈的递增性
while stack and p[stack[-1]] > p[i]:
stack.pop()
# 如果栈不为空,栈顶元素的价格就是优惠价格
if stack and p[stack[-1]] <= p[i]:
total_discount += p[stack[-1]]
# 当前商品索引入栈
stack.append(i)
return total_discount
# 测试样例
if __name__ == '__main__':
print(solution(5, [9, 4, 5, 2, 4])) # 输出: 6
print(solution(4, [1, 2, 3, 5])) # 输出: 6
print(solution(4, [4, 3, 2, 1])) # 输出: 0
这样,代码既高效又清晰,可以很好地解决这个问题。