持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第10天,点击查看活动详情
测试岗位也越来卷了,除了基本的功能测试外,还要有编程基础、脚本经验才脱颖而出。
怎么才能提高我们的编程能力呢,刷LeetCode是最佳的途径之一,话不多数,刷题走起~
一、题目描述:
-
题目内容
-
题目示例
-
题目解析
1 <= prices.length <= 5001 <= prices[i] <= 10^3
二、思路分析:
我们今天拿到本题是 leetcode 难度为简单题 1475. 商品折扣后的最终价格。根据题目内容要求根据prices数组价格,按照指定的折扣规则进行计算出现相应的支付价格数组,则折扣规则为:
- 第i件商品,满足j>i 且 prices[j] <= prices[i] 的最小索引
- 如果不满足,则该商品则没有折扣,返回支付价格
根据题目内容,针对题目我们可以使用如下两种方法求解,思路如下:
-
方法一:遍历求解
- 根据题目要求第i个商品的折扣,需要从[i+1,len(prices)]范围找小于prices[i]的最小下标
- 因此遍历prices数组时,只要找到第一个小于prices[i]的折扣即可
- 使用for循环遍历取prices数组中每一件商品,j的坐标被赋值为i+1,进入找最小下标
- 当prices[j]小于等于prices[i]则将prices[i]更新为prices[i]-prices[j]
- 直到遍历完prices数组,结果返回prices
class Solution(object): def finalPrices(self, prices): """ :type prices: List[int] :rtype: List[int] """ for i in range(len(prices)-1): j = i +1 while j < len(prices): if prices[j] <= prices[i]: prices[i] = prices[i] - prices[j] break j +=1 return prices -
方法二:单调栈
- 栈的特点是先进后出,本题在找prices[j] <= prices[i]的最小坐标时,可以使用栈的特点来查找,那么这个栈具有单调递增的
- 倒序遍历prices,使用栈维护右边第一个最小的元素,使得栈具有单调递增性
- 当栈顶🆙元素大于prices[i]时,则弹出栈,直到找到st[-1]小于等于prices[i]
- prices[i]则更新为prices[i] = p - st[-1]
- 当st为空时,如则说明当前位置右边没有更大的元素,则prices[i]为原价
- 并将元素i原值,添加到栈st内
class Solution(object): def finalPrices(self, prices): """ :type prices: List[int] :rtype: List[int] """ n = len(prices) st = [0] for i in range(n-1,-1,-1): p = prices[i] while len(st) > 1 and st[-1] > prices[i]: st.pop() prices[i] = p - st[-1] st.append(p) return prices -
单调栈总结
左边、右边第一个较大、较小的数字,可以考虑用单调栈
- 求右边第一个较大的数字:逆序遍历,单调递减栈 —— 如果当前元素大于等于栈顶元素,则栈顶出栈。
- 求右边第一个较小的数字:逆序遍历,单调递增栈 —— 如果当前元素小于等于栈顶元素,则栈顶出栈。
- 求左边第一个较大的数字:正序遍历,单调递减栈 —— 如果当前元素大于等于栈顶元素,则栈顶出栈。
- 求左边第一个较小的数字:正序遍历,单调递增栈 —— 如果当前元素小于等于栈顶元素,则栈顶出栈。
三、总结:
本题对数组元素进行处理,当要指定元素的右边或者左边第一个元素值,我们可以使用单调栈来处理,对比暴力求法,可以高效处理大量数据。AC提交记录如下:
- 时间复杂度:O(n),n为prices数组长度,一次遍历
- 空间复杂度:O(n),栈处理需要使用额外空间
以上是本期内容,欢迎大佬们点赞评论,下期见~~~