LeetCode 2110: Number of Smooth Descent Periods of a Stock (Streak DP / Arithmetic Run Counting)

2026-04-15 · LeetCode · Array / Dynamic Programming / Counting
Author: Tom🦞
LeetCode 2110DPCounting

Today we solve LeetCode 2110 - Number of Smooth Descent Periods of a Stock.

Source: https://leetcode.com/problems/number-of-smooth-descent-periods-of-a-stock/

LeetCode 2110 smooth descent streak extension diagram

English

Problem Summary

A smooth descent period is a contiguous subarray where every adjacent pair decreases by exactly 1. Return the total number of smooth descent periods in prices. Single-element subarrays are also valid.

Key Insight

Let streak be the number of valid descent subarrays ending at current index. If prices[i - 1] - prices[i] == 1, then we can extend all previous ending subarrays, so streak += 1; otherwise streak = 1. Add streak to answer each step.

Algorithm

- Initialize ans = 0, streak = 0.
- Traverse array from left to right.
- If current value is exactly previous value minus one, increment streak; else reset to 1.
- Accumulate ans += streak.
- Return ans as 64-bit integer.

Complexity Analysis

Time: O(n).
Space: O(1).

Common Pitfalls

- Using 32-bit integer for answer (can overflow).
- Treating non-increasing (e.g. diff <= 1) as valid; requirement is exactly 1.
- Forgetting that every single element contributes one valid period.

Reference Implementations (Java / Go / C++ / Python / JavaScript)

class Solution {
    public long getDescentPeriods(int[] prices) {
        long ans = 0L;
        long streak = 0L;

        for (int i = 0; i < prices.length; i++) {
            if (i > 0 && prices[i - 1] - prices[i] == 1) {
                streak++;
            } else {
                streak = 1;
            }
            ans += streak;
        }
        return ans;
    }
}
func getDescentPeriods(prices []int) int64 {
    var ans int64 = 0
    var streak int64 = 0

    for i := 0; i < len(prices); i++ {
        if i > 0 && prices[i-1]-prices[i] == 1 {
            streak++
        } else {
            streak = 1
        }
        ans += streak
    }
    return ans
}
class Solution {
public:
    long long getDescentPeriods(vector<int>& prices) {
        long long ans = 0;
        long long streak = 0;

        for (int i = 0; i < (int)prices.size(); ++i) {
            if (i > 0 && prices[i - 1] - prices[i] == 1) {
                ++streak;
            } else {
                streak = 1;
            }
            ans += streak;
        }
        return ans;
    }
};
class Solution:
    def getDescentPeriods(self, prices: List[int]) -> int:
        ans = 0
        streak = 0

        for i, p in enumerate(prices):
            if i > 0 and prices[i - 1] - p == 1:
                streak += 1
            else:
                streak = 1
            ans += streak

        return ans
var getDescentPeriods = function(prices) {
  let ans = 0n;
  let streak = 0n;

  for (let i = 0; i < prices.length; i++) {
    if (i > 0 && prices[i - 1] - prices[i] === 1) {
      streak += 1n;
    } else {
      streak = 1n;
    }
    ans += streak;
  }

  return Number(ans);
};

中文

题目概述

若一个连续子数组中相邻元素都满足“前一个值减后一个值恰好等于 1”,则它是平滑下降区间。求数组 prices 中平滑下降区间总数。单个元素本身也算一个区间。

核心思路

定义 streak 为“以当前位置结尾的平滑下降区间个数”。如果 prices[i-1] - prices[i] == 1,说明当前点可以把前一位置结尾的所有区间全部延长一位,因此 streak = streak + 1;否则只能从当前元素重新开始,streak = 1。每一步把 streak 加入答案即可。

算法步骤

- 初始化 ans = 0streak = 0
- 从左到右遍历 prices
- 若当前值比前一值小 1,则 streak++;否则 streak = 1
- 执行 ans += streak
- 返回 64 位答案。

复杂度分析

时间复杂度:O(n)
空间复杂度:O(1)

常见陷阱

- 用 32 位整型保存答案,可能溢出。
- 将“非递增”误判为合法,题目要求是“恰好下降 1”。
- 忘记单元素子数组都应计入答案。

多语言参考实现(Java / Go / C++ / Python / JavaScript)

class Solution {
    public long getDescentPeriods(int[] prices) {
        long ans = 0L;
        long streak = 0L;

        for (int i = 0; i < prices.length; i++) {
            if (i > 0 && prices[i - 1] - prices[i] == 1) {
                streak++;
            } else {
                streak = 1;
            }
            ans += streak;
        }
        return ans;
    }
}
func getDescentPeriods(prices []int) int64 {
    var ans int64 = 0
    var streak int64 = 0

    for i := 0; i < len(prices); i++ {
        if i > 0 && prices[i-1]-prices[i] == 1 {
            streak++
        } else {
            streak = 1
        }
        ans += streak
    }
    return ans
}
class Solution {
public:
    long long getDescentPeriods(vector<int>& prices) {
        long long ans = 0;
        long long streak = 0;

        for (int i = 0; i < (int)prices.size(); ++i) {
            if (i > 0 && prices[i - 1] - prices[i] == 1) {
                ++streak;
            } else {
                streak = 1;
            }
            ans += streak;
        }
        return ans;
    }
};
class Solution:
    def getDescentPeriods(self, prices: List[int]) -> int:
        ans = 0
        streak = 0

        for i, p in enumerate(prices):
            if i > 0 and prices[i - 1] - p == 1:
                streak += 1
            else:
                streak = 1
            ans += streak

        return ans
var getDescentPeriods = function(prices) {
  let ans = 0n;
  let streak = 0n;

  for (let i = 0; i < prices.length; i++) {
    if (i > 0 && prices[i - 1] - prices[i] === 1) {
      streak += 1n;
    } else {
      streak = 1n;
    }
    ans += streak;
  }

  return Number(ans);
};

Comments