Java C++ 算法题解leetcode145商品折扣后最终价格单调栈
作者:AnjaVon 发布时间:2023-09-16 23:29:42
标签:Java,C++,商品折扣,算法,单调栈
题目要求
思路一:暴力模拟
由于数据范围不算离谱,所以直接遍历解决可行。
Java
class Solution {
public int[] finalPrices(int[] prices) {
int n = prices.length;
int[] res = new int[n];
for (int i = 0; i < n; i++) {
int discount = 0;
for (int j = i + 1; j < n && discount == 0; j++) {
if (prices[j] <= prices[i])
discount = prices[j];
}
res[i] = prices[i] - discount;
}
return res;
}
}
时间复杂度:O(n^2)
空间复杂度:O(n)
C++
class Solution {
public:
vector<int> finalPrices(vector<int>& prices) {
int n = prices.size();
vector<int> res(n);
for (int i = 0; i < n; i++) {
int discount = 0;
for (int j = i + 1; j < n && discount == 0; j++) {
if (prices[j] <= prices[i])
discount = prices[j];
}
res[i] = prices[i] - discount;
}
return res;
}
};
时间复杂度:O(n^2)
空间复杂度:O(n)
Rust
impl Solution {
pub fn final_prices(prices: Vec<i32>) -> Vec<i32> {
let n = prices.len();
let mut res = vec![0;n];
(0..n).for_each(|i| {
res[i] = prices[i] - ((i + 1)..n).find(|&j| prices[j] <= prices[i]).map_or(0, |j| prices[j]);
});
res
}
}
遍历存每次的count,最后再遍历计算得出结果
impl Solution {
pub fn final_prices(prices: Vec<i32>) -> Vec<i32> {
let n = prices.len();
let mut discount = vec![0;n];
for j in 1..n {
for i in 0..j {
if discount[i] == 0 && prices[j] <= prices[i] {
discount[i] = prices[j];
}
}
}
prices.iter().zip(discount.iter()).map(|(&x, &y)| x - y).collect::<Vec<i32>>()
}
}
时间复杂度:O(n^2)
空间复杂度:O(n)
思路二:单调栈
是个逆向思维,不考虑谁是我的折扣,而去考虑我可以是谁的折扣。已知的一个prices[j]只能折扣其左边最近的几个大于它的值,按这个思路分析单调和栈:
若当前处理值小于末尾,那么它就可以作为末尾元素的折扣【因为它是末尾元素后面第一个小于它的值】,将末尾元素取出、折扣、放入已折扣数组(即结果数组),一直重复到容器末尾元素小于当前处理值,则将当前处理值放入容器【为避免该值不可打折造成缺漏,此时将其价格同步至已折扣数组】。
若当前处理的值高于容器内的值,那么它不能作为里面任何一者的折扣,因此直接加入容器。
从前向后依次遍历prices,遇到需要打折的商品,将其下标放入一个容器:
由此可知,加入容器值会大于容器内的其它值,该容器是单调递增的。此外,处理的一直是容器末尾的元素,添加也是直接补在末尾,所以符合栈的结构。
Java
class Solution {
public int[] finalPrices(int[] prices) {
int n = prices.length;
int[] res = new int[n]; // 已打折价格
Deque<Integer> sta = new ArrayDeque<>(); // 待打折下标
for (int i = 0; i < n; i++) {
while (!sta.isEmpty() && prices[sta.peekLast()] >= prices[i]) {
int idx = sta.pollLast();
res[idx] = prices[idx] - prices[i];
}
sta.addLast(i); // 最高
res[i] = prices[i];
}
return res;
}
}
时间复杂度:O(n)
空间复杂度:O(n)
C++
class Solution {
public:
vector<int> finalPrices(vector<int>& prices) {
int n = prices.size();
vector<int> res(n); // 已打折价格
stack<int> sta; // 待打折下标
for (int i = 0; i < n; i++) {
while (!sta.empty() && prices[sta.top()] >= prices[i]) {
int idx = sta.top();
sta.pop();
res[idx] = prices[idx] - prices[i];
}
sta.push(i); // 最高
res[i] = prices[i];
}
return res;
}
};
时间复杂度:O(n)
空间复杂度:O(n)
Rust
impl Solution {
pub fn final_prices(prices: Vec<i32>) -> Vec<i32> {
let n = prices.len();
let mut res = vec![0;n]; // 已打折价格
let mut sta = vec![]; // 待打折下标
for i in 0..n {
while let Some(&idx) = sta.last() {
if prices[idx] < prices[i] {
break;
}
sta.pop();
res[idx] = prices[idx] - prices[i];
}
sta.push(i); // 最高
res[i] = prices[i];
}
res
}
}
时间复杂度:O(n)
空间复杂度:O(n)
来源:https://juejin.cn/post/7138321057219346463


猜你喜欢
- Java Function的使用一、方法介绍表示接受一个参数并产生结果的函数。参数类型 T - 函数输入的类型R - 函数的结果类型方法介绍
- 主要介绍:1.任务队列2.拒绝策略(抛出异常、直接丢弃、阻塞、临时队列)3.init( min )4.active5.maxmin<=
- Struts提供了一个更简单的方式来处理未捕获的异常,并将用户重定向到一个专门的错误页面。您可以轻松地Struts配置到不同的异常有不同的错
- 一、前言最近在看android fragment与Activity进行数据传递的部分,看到了接口回调的内容,今天来总结一下。二、回调的含义和
- 本文实例讲述了Android编程设计模式之状态模式。分享给大家供大家参考,具体如下:一、介绍状态模式中的行为是由状态来决定的,不同的状态下有
- Android CardView详解Android5.0中向我们介绍了一个全新的控件–CardView,从本质上看,可以将Car
- public class Wrapper { public static void main
- 一直以来,Java/Spring开发被认为是笨重的代表,无法快速生成项目原型和骨架。所以,Spring推出了Spring Roo这个项目,帮
- 包的内容包的内容应该仔细设计,使其只包含在功能上相关的类和接口。包中的类可以自由地访问该包中其他类的非私有成员,有些类甚至可能有足够的权限去
- 在ios7中,苹果的原生态应用几乎都能够通过向右滑动来返回到前一个页面,这样可以避免用户在单手操作时用大拇指去点击那个遥远的返回键(ipho
- 介绍: 本文章主要针对web项目中的两个问题进行详细解析介绍:1- 页面跳转404,即controller转发无法跳转页面问题;2- 静态资
- 前言:在 Java 中,常用的锁有两种:synchronized(内置锁)和 ReentrantLock(可重入锁),二者的功效都是相同得,
- idea切换分支时,修改过的代码文件全部不见了找了一下问题,切换分支时,idea自动会创建暂存文件,点开,右边View --> 即可显
- 文章描述这个效果可能很多人都在抖音看到过,即把一个短视频,转成数字、字母等乱码组成的形式进行播放。开发环境.NET Framework版本:
- Android中很多产品(比如360手机助手、网易菜单...)都采用侧滑菜单的展现形式,采用这种展现形式1、能把更多的展现内容都存放在菜单中
- 最近因为fastjson安全漏洞,升级jar包时,踩了一些坑。新版本FastJsonHttpMessageConverter初始化,默认设置
- 由于公司的开发团队偏向于使用Java技术,而且公司倡导学习开源技术,所以我选择用Java语言来进行Selenium WebDriver的自动
- 本文实例讲述了C#实现对Json字符串处理方法,分享给大家供大家参考。具体分析如下:一般对于web应用开发人员来说对Json字符串都会很熟悉
- @ConfigurationProperties加载外部配置@ConfigurationProperties可以将外部配置文件(比如appl
- 一、问题描述在C#中is,as,using关键字具有其特点及使用场景,其中is关键字用于检查该对象是否与给定类型兼容,as关键字用于将对象转