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
0
投稿
猜你喜欢
- 现在的项目基本上都是java web项目,所以导入jar包会出现问题,主要介绍一下java项目与javaweb项目的区别:java项目:在c
- 今天讲解一下Fragment的控制,主要是切换View和页面替换等操作。还有就是如何获取Fragment的管理对象,以及与Activity的
- 本节我们来探讨如何使用Feign构造多参数的请求。笔者以GET以及POST方法的请求为例进行讲解,其他方法(例如DELETE、PUT等)的请
- 背景最近好几个项目在运行过程中客户都提出文件上传大小的限制能否设置的大一些,用户经常需要上传好几个G的资料文件,如图纸,视频等,并且需要在上
- 策略模式的应用场景策略模式是否要使用,取决于业务场景是否符合,有没有必要。是否符合如果业务是处于不同的场景时,采取不同的处理方式的话,就满足
- 环境:VS2019+Qt5.121. CLR库安装 &nb
- 在使用Gateway 调用一个文件上传服务时 前端传来的File的base64字符串怎么都接受不到 但是用Body方式请求就能接收到后来经过
- redis redisson 集合操作相关类及接口Rlist:链表public interface RList<V> exten
- spring cloud gateway获取请求的真实地址在使用spring cloud gateway的时候,路由一般配置为服务名例如 l
- 一、输入输出流对象cout:标准输出流cerr:标准出凑 和cout(只是用于如果是错误时要输出的)cin :&nb
- 网络中数据传输经常是xml或者json,现在做的一个项目之前调其他系统接口都是返回的xml格式,刚刚遇到一个返回json格式数据的接口,通过
- 使用HTTPclient访问url获得数据最近项目上有个小功能需要调用第三方的http接口取数据,用到了HTTPclient,算是做个笔记吧
- 本文实例讲述了Android+SQLite数据库实现的生词记事本功能。分享给大家供大家参考,具体如下:主activity命名为Dict:代码
- Spring Boot 2.7.6整合redis与低版本的区别最近在写程序的时候参考了之前写过的一篇文章spring boot整合redis
- 前言 因为自己在做的一个小软件里面需要用到从A-Z排序的ListView,所以自然而然的想到了微信的联系人,我想要的就是那样的效果。本来没
- 在学会了java中io流的使用后,我们对于数组的排序,又多了一种使用方法。大家知道流处理数据的效率是比较理想的,那么在具体操作数组排序上,很
- ThreadLocal简介变量值的共享可以使用public static的形式,所有线程都使用同一个变量,如果想实现每一个线程都有自己的共享
- 本文实例讲述了Java Socket实现单线程通信的方法。分享给大家供大家参考,具体如下:现在做Java直接使用Socket的情况是越来越少
- import java.io.BufferedInputStream;import java.io.BufferedOutputStream
- 在并发多线程的情况下,为了保证数据安全性,一般我们会对数据进行加锁,通常使用Synchronized或者ReentrantLock同步锁。S