2110.股票平滑下跌阶段的数目:数学(一次遍历)

【LetMeFly】2110.股票平滑下跌阶段的数目:数学(一次遍历)

力扣题目链接:https://leetcode.cn/problems/number-of-smooth-descent-periods-of-a-stock/

给你一个整数数组 prices ,表示一支股票的历史每日股价,其中 prices[i] 是这支股票第 i 天的价格。

一个 平滑下降的阶段 定义为:对于 连续一天或者多天 ,每日股价都比 前一日股价恰好少 1 ,这个阶段第一天的股价没有限制。

请你返回 平滑下降阶段 的数目。

 

示例 1:

输入:prices = [3,2,1,4]
输出:7
解释:总共有 7 个平滑下降阶段:
[3], [2], [1], [4], [3,2], [2,1] 和 [3,2,1]
注意,仅一天按照定义也是平滑下降阶段。

示例 2:

输入:prices = [8,6,7,7]
输出:4
解释:总共有 4 个连续平滑下降阶段:[8], [6], [7] 和 [7]
由于 8 - 6 ≠ 1 ,所以 [8,6] 不是平滑下降阶段。

示例 3:

输入:prices = [1]
输出:1
解释:总共有 1 个平滑下降阶段:[1]

 

提示:

  • 1 <= prices.length <= 105
  • 1 <= prices[i] <= 105

解题方法:遍历

假设有$3$个连续下滑天$[3, 2, 1]$,那么可以有$3, 2, 1$(连续3天共1种)、$3, 2$、$2, 1$(连续2天共2种)、$3$、$2$、$1$(连续1天共3种)这共计$1+2+3=\frac{3(3+1)}{2}=6$种平滑下降阶段

同样的,$n$个连续下滑天就有$\frac{n(n+1)}2$种平滑下降阶段

因此,我们只需要遍历一遍,看下原始数组中有多少连续下滑天,并将每个连续下滑天的平滑下降阶段种类数求和即可。

具体做法

具体而言,可以使用两个变量:$last$和$cnt$分别记录上一天的价格和当前连续下滑天,遇到连续下滑天中断的情况就计算一次$ans$,最后返回前也计算一次$ans$。

时空复杂度

  • 时间复杂度$O(len(prices))$
  • 空间复杂度$O(1)$

AC代码

C++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
* @LastEditTime: 2025-12-15 18:52:23
*/
typedef long long ll;
class Solution {
public:
ll getDescentPeriods(vector<int>& prices) {
ll ans = 0, cnt = 0;
int last = 0;
for (int t : prices) {
if (t != last - 1) {
ans += cnt * (cnt + 1) / 2;
// printf("t = %d, cnt = %lld\n", t, cnt);
cnt = 0;
}
last = t;
cnt++;
}
return ans + cnt * (cnt + 1) / 2;
}
};

Python

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
'''
LastEditTime: 2025-12-15 18:54:39
'''
from typing import List

class Solution:
def getDescentPeriods(self, prices: List[int]) -> int:
ans = last = cnt = 0
for p in prices:
if p != last - 1:
ans += cnt * (cnt + 1) // 2
cnt = 0
cnt += 1
last = p
return ans + cnt * (cnt + 1) // 2

Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
* @LastEditTime: 2025-12-15 21:37:22
*/
class Solution {
public long getDescentPeriods(int[] prices) {
long ans = 0, cnt = 0;
for (int last = 0, i = 0; i <= prices.length; i++) {
if (i == prices.length || prices[i] != last - 1) {
ans += cnt * (cnt + 1) / 2;
cnt = 0;
}
cnt++;
if (i < prices.length) {
last = prices[i];
}
}
return ans;
}
}

Go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
* @LastEditTime: 2025-12-15 21:35:08
*/
package main

func getDescentPeriods(prices []int) (ans int64) {
var cnt int64
last := 0
for i := 0; i <= len(prices); i++ {
if i == len(prices) || prices[i] != last - 1 {
ans += cnt * (cnt + 1) / 2
cnt = 0
}
cnt++
if i < len(prices) {
last = prices[i]
}
}
return
}

Rust

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
* @LastEditTime: 2025-12-15 21:41:17
*/
impl Solution {
pub fn get_descent_periods(prices: Vec<i32>) -> i64 {
let mut ans: i64 = 0;
let mut cnt: i64 = 0;
let mut last: i32 = 0;
for p in prices { // 一借不还
if p != last - 1 {
ans += cnt * (cnt + 1) / 2;
cnt = 0;
}
cnt += 1;
last = p;
}
ans + cnt * (cnt + 1) / 2
}
}

End

今天跌得可不轻啊

The Real End, Thanks!

同步发文于CSDN和我的个人博客,原创不易,转载经作者同意后请附上原文链接哦~

千篇源码题解已开源


2110.股票平滑下跌阶段的数目:数学(一次遍历)
https://blog.letmefly.xyz/2025/12/15/LeetCode 2110.股票平滑下跌阶段的数目/
作者
发布于
2025年12月15日
许可协议