LeetCode 2110: Number of Smooth Descent Periods of a Stock (Streak DP / Arithmetic Run Counting)
LeetCode 2110DPCountingToday 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/
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 ansvar 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 = 0、streak = 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 ansvar 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