Skip to content

Commit 1736b25

Browse files
authored
feat: add solutions to lc problem: No.0901 (#1754)
No.0901.Online Stock Span
1 parent 4bb142b commit 1736b25

File tree

5 files changed

+64
-50
lines changed

5 files changed

+64
-50
lines changed

solution/0900-0999/0901.Online Stock Span/README.md

+20-20
Original file line numberDiff line numberDiff line change
@@ -60,17 +60,17 @@ stockSpanner.next(85); // 返回 6
6060

6161
**方法一:单调栈**
6262

63-
根据题目描述,我们可以知道,对于当日价格 `price`,从这个价格开始往前找,找到第一个比这个价格大的价格,这两个价格的下标差 `cnt` 就是当日价格的跨度。
63+
根据题目描述,我们可以知道,对于当日价格 $price$,从这个价格开始往前找,找到第一个比这个价格大的价格,这两个价格的下标差 $cnt$ 就是当日价格的跨度。
6464

6565
这实际上是经典的单调栈模型,找出左侧第一个比当前元素大的元素。
6666

67-
我们维护一个从栈底到栈顶价格单调递减的栈,栈中每个元素存放的是 `(price, cnt)` 数据对,其中 `price` 表示价格,`cnt` 表示当前价格的跨度。
67+
我们维护一个从栈底到栈顶价格单调递减的栈,栈中每个元素存放的是 $(price, cnt)$ 数据对,其中 $price$ 表示价格,而 $cnt$ 表示当前价格的跨度。
6868

69-
出现价格 `price` 时,我们将其与栈顶元素进行比较,如果栈顶元素的价格小于等于 `price`,则将当日价格的跨度 `cnt` 加上栈顶元素的跨度,然后将栈顶元素出栈,直到栈顶元素的价格大于 `price`,或者栈为空为止。
69+
出现价格 $price$ 时,我们将其与栈顶元素进行比较,如果栈顶元素的价格小于等于 $price$,则将当日价格的跨度 $cnt$ 加上栈顶元素的跨度,然后将栈顶元素出栈,直到栈顶元素的价格大于 $price$,或者栈为空为止。
7070

71-
最后将 `(price, cnt)` 入栈,返回 `cnt` 即可。
71+
最后将 $(price, cnt)$ 入栈,返回 $cnt$ 即可。
7272

73-
时间复杂度 $O(n)$,其中 $n$ 为 `next` 函数的调用次数。
73+
时间复杂度 $O(n)$,其中 $n$ 为 $next$ 函数的调用次数。
7474

7575
<!-- tabs:start -->
7676

@@ -138,7 +138,7 @@ public:
138138
cnt += stk.top().second;
139139
stk.pop();
140140
}
141-
stk.push({price, cnt});
141+
stk.emplace(price, cnt);
142142
return cnt;
143143
}
144144

@@ -187,19 +187,19 @@ type pair struct{ price, cnt int }
187187

188188
```ts
189189
class StockSpanner {
190-
private stack: [number, number][];
190+
private stk: number[][];
191191

192192
constructor() {
193-
this.stack = [[Infinity, -1]];
193+
this.stk = [];
194194
}
195195

196196
next(price: number): number {
197-
let res = 1;
198-
while (this.stack[this.stack.length - 1][0] <= price) {
199-
res += this.stack.pop()[1];
197+
let cnt = 1;
198+
while (this.stk.length && this.stk.at(-1)[0] <= price) {
199+
cnt += this.stk.pop()[1];
200200
}
201-
this.stack.push([price, res]);
202-
return res;
201+
this.stk.push([price, cnt]);
202+
return cnt;
203203
}
204204
}
205205

@@ -215,7 +215,7 @@ class StockSpanner {
215215
```rust
216216
use std::collections::VecDeque;
217217
struct StockSpanner {
218-
stack: VecDeque<(i32, i32)>,
218+
stk: VecDeque<(i32, i32)>,
219219
}
220220

221221

@@ -226,17 +226,17 @@ struct StockSpanner {
226226
impl StockSpanner {
227227
fn new() -> Self {
228228
Self {
229-
stack: vec![(i32::MAX, -1)].into_iter().collect()
229+
stk: vec![(i32::MAX, -1)].into_iter().collect()
230230
}
231231
}
232232

233233
fn next(&mut self, price: i32) -> i32 {
234-
let mut res = 1;
235-
while self.stack.back().unwrap().0 <= price {
236-
res += self.stack.pop_back().unwrap().1;
234+
let mut cnt = 1;
235+
while self.stk.back().unwrap().0 <= price {
236+
cnt += self.stk.pop_back().unwrap().1;
237237
}
238-
self.stack.push_back((price, res));
239-
res
238+
self.stk.push_back((price, cnt));
239+
cnt
240240
}
241241
}
242242

solution/0900-0999/0901.Online Stock Span/README_EN.md

+29-15
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,20 @@ stockSpanner.next(85); // return 6
5151

5252
## Solutions
5353

54+
**Solution 1: Monotonic Stack**
55+
56+
According to the problem description, we can know that for the price price on a certain day, we need to find the first price that is greater than price when looking back, and the difference between the indices of these two prices is the span of the price on that day.
57+
58+
This is actually a classic monotonic stack model, which finds the first element on the left that is greater than the current element.
59+
60+
We maintain a stack that is monotonically decreasing from the bottom to the top in terms of prices. Each element in the stack stores a pair of $(price, cnt)$, where $price$ represents the price, and $cnt$ represents the span of the current price.
61+
62+
When encountering a price $price$, we compare it with the top element of the stack. If the price of the top element of the stack is less than or equal to price, we add the span cnt of the current price to the span of the top element of the stack, and then pop the top element of the stack until the price of the top element of the stack is greater than price, or the stack is empty.
63+
64+
Finally, we push $(price, cnt)$ onto the stack and return $cnt$.
65+
66+
The time complexity is $O(n)$, where $n$ is the number of calls to the next function.
67+
5468
<!-- tabs:start -->
5569

5670
### **Python3**
@@ -113,7 +127,7 @@ public:
113127
cnt += stk.top().second;
114128
stk.pop();
115129
}
116-
stk.push({price, cnt});
130+
stk.emplace(price, cnt);
117131
return cnt;
118132
}
119133

@@ -162,19 +176,19 @@ type pair struct{ price, cnt int }
162176

163177
```ts
164178
class StockSpanner {
165-
private stack: [number, number][];
179+
private stk: number[][];
166180

167181
constructor() {
168-
this.stack = [[Infinity, -1]];
182+
this.stk = [];
169183
}
170184

171185
next(price: number): number {
172-
let res = 1;
173-
while (this.stack[this.stack.length - 1][0] <= price) {
174-
res += this.stack.pop()[1];
186+
let cnt = 1;
187+
while (this.stk.length && this.stk.at(-1)[0] <= price) {
188+
cnt += this.stk.pop()[1];
175189
}
176-
this.stack.push([price, res]);
177-
return res;
190+
this.stk.push([price, cnt]);
191+
return cnt;
178192
}
179193
}
180194

@@ -190,7 +204,7 @@ class StockSpanner {
190204
```rust
191205
use std::collections::VecDeque;
192206
struct StockSpanner {
193-
stack: VecDeque<(i32, i32)>,
207+
stk: VecDeque<(i32, i32)>,
194208
}
195209

196210

@@ -201,17 +215,17 @@ struct StockSpanner {
201215
impl StockSpanner {
202216
fn new() -> Self {
203217
Self {
204-
stack: vec![(i32::MAX, -1)].into_iter().collect()
218+
stk: vec![(i32::MAX, -1)].into_iter().collect()
205219
}
206220
}
207221

208222
fn next(&mut self, price: i32) -> i32 {
209-
let mut res = 1;
210-
while self.stack.back().unwrap().0 <= price {
211-
res += self.stack.pop_back().unwrap().1;
223+
let mut cnt = 1;
224+
while self.stk.back().unwrap().0 <= price {
225+
cnt += self.stk.pop_back().unwrap().1;
212226
}
213-
self.stack.push_back((price, res));
214-
res
227+
self.stk.push_back((price, cnt));
228+
cnt
215229
}
216230
}
217231

solution/0900-0999/0901.Online Stock Span/Solution.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ class StockSpanner {
99
cnt += stk.top().second;
1010
stk.pop();
1111
}
12-
stk.push({price, cnt});
12+
stk.emplace(price, cnt);
1313
return cnt;
1414
}
1515

solution/0900-0999/0901.Online Stock Span/Solution.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::collections::VecDeque;
22
struct StockSpanner {
3-
stack: VecDeque<(i32, i32)>,
3+
stk: VecDeque<(i32, i32)>,
44
}
55

66

@@ -11,17 +11,17 @@ struct StockSpanner {
1111
impl StockSpanner {
1212
fn new() -> Self {
1313
Self {
14-
stack: vec![(i32::MAX, -1)].into_iter().collect()
14+
stk: vec![(i32::MAX, -1)].into_iter().collect()
1515
}
1616
}
1717

1818
fn next(&mut self, price: i32) -> i32 {
19-
let mut res = 1;
20-
while self.stack.back().unwrap().0 <= price {
21-
res += self.stack.pop_back().unwrap().1;
19+
let mut cnt = 1;
20+
while self.stk.back().unwrap().0 <= price {
21+
cnt += self.stk.pop_back().unwrap().1;
2222
}
23-
self.stack.push_back((price, res));
24-
res
23+
self.stk.push_back((price, cnt));
24+
cnt
2525
}
2626
}
2727

solution/0900-0999/0901.Online Stock Span/Solution.ts

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
class StockSpanner {
2-
private stack: [number, number][];
2+
private stk: number[][];
33

44
constructor() {
5-
this.stack = [[Infinity, -1]];
5+
this.stk = [];
66
}
77

88
next(price: number): number {
9-
let res = 1;
10-
while (this.stack[this.stack.length - 1][0] <= price) {
11-
res += this.stack.pop()[1];
9+
let cnt = 1;
10+
while (this.stk.length && this.stk.at(-1)[0] <= price) {
11+
cnt += this.stk.pop()[1];
1212
}
13-
this.stack.push([price, res]);
14-
return res;
13+
this.stk.push([price, cnt]);
14+
return cnt;
1515
}
1616
}
1717

0 commit comments

Comments
 (0)