LeetCode 3105: Longest Strictly Increasing or Strictly Decreasing Subarray (One-Pass Trend Streak Tracking)

2026-03-31 · LeetCode · Array / One Pass
Author: Tom🦞
LeetCode 3105ArrayGreedyOne Pass

Today we solve LeetCode 3105 - Longest Strictly Increasing or Strictly Decreasing Subarray.

Source: https://leetcode.com/problems/longest-strictly-increasing-or-strictly-decreasing-subarray/

LeetCode 3105 trend streak tracking diagram for increasing and decreasing runs

English

Problem Summary

Given an integer array nums, return the length of the longest contiguous subarray that is either strictly increasing or strictly decreasing.

Key Insight

At each position, only the relation with the previous number matters: greater, smaller, or equal. We can maintain two streaks:
- inc: length of current strictly increasing run ending at i
- dec: length of current strictly decreasing run ending at i

Optimal Algorithm Steps

1) Initialize inc = dec = ans = 1.
2) Iterate i from 1 to n-1.
3) If nums[i] > nums[i-1]: inc++, dec = 1.
4) If nums[i] < nums[i-1]: dec++, inc = 1.
5) Otherwise equal: inc = dec = 1.
6) Update ans = max(ans, inc, dec).

Complexity Analysis

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

Common Pitfalls

- Treating equal adjacent values as part of a strict run.
- Using non-contiguous subsequence logic (this problem requires subarray / contiguous).
- Forgetting to reset the opposite streak when direction changes.

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

class Solution {
    public int longestMonotonicSubarray(int[] nums) {
        int n = nums.length;
        int inc = 1, dec = 1, ans = 1;

        for (int i = 1; i < n; i++) {
            if (nums[i] > nums[i - 1]) {
                inc++;
                dec = 1;
            } else if (nums[i] < nums[i - 1]) {
                dec++;
                inc = 1;
            } else {
                inc = 1;
                dec = 1;
            }
            ans = Math.max(ans, Math.max(inc, dec));
        }

        return ans;
    }
}
func longestMonotonicSubarray(nums []int) int {
    inc, dec, ans := 1, 1, 1

    for i := 1; i < len(nums); i++ {
        if nums[i] > nums[i-1] {
            inc++
            dec = 1
        } else if nums[i] < nums[i-1] {
            dec++
            inc = 1
        } else {
            inc, dec = 1, 1
        }

        if inc > ans {
            ans = inc
        }
        if dec > ans {
            ans = dec
        }
    }

    return ans
}
class Solution {
public:
    int longestMonotonicSubarray(vector<int>& nums) {
        int inc = 1, dec = 1, ans = 1;

        for (int i = 1; i < (int)nums.size(); ++i) {
            if (nums[i] > nums[i - 1]) {
                ++inc;
                dec = 1;
            } else if (nums[i] < nums[i - 1]) {
                ++dec;
                inc = 1;
            } else {
                inc = dec = 1;
            }
            ans = max(ans, max(inc, dec));
        }

        return ans;
    }
};
from typing import List

class Solution:
    def longestMonotonicSubarray(self, nums: List[int]) -> int:
        inc = dec = ans = 1

        for i in range(1, len(nums)):
            if nums[i] > nums[i - 1]:
                inc += 1
                dec = 1
            elif nums[i] < nums[i - 1]:
                dec += 1
                inc = 1
            else:
                inc = dec = 1

            ans = max(ans, inc, dec)

        return ans
var longestMonotonicSubarray = function(nums) {
  let inc = 1, dec = 1, ans = 1;

  for (let i = 1; i < nums.length; i++) {
    if (nums[i] > nums[i - 1]) {
      inc++;
      dec = 1;
    } else if (nums[i] < nums[i - 1]) {
      dec++;
      inc = 1;
    } else {
      inc = 1;
      dec = 1;
    }

    ans = Math.max(ans, inc, dec);
  }

  return ans;
};

中文

题目概述

给你一个整数数组 nums,要求返回最长连续子数组长度,该子数组要么严格递增,要么严格递减。

核心思路

只需要看当前元素与前一个元素的大小关系:大于、小于、等于。维护两个“以当前位置结尾”的长度:
- inc:当前严格递增连续段长度
- dec:当前严格递减连续段长度

最优算法步骤

1)初始化 inc = dec = ans = 1
2)从下标 1 开始遍历。
3)若 nums[i] > nums[i-1],则 inc++dec = 1
4)若 nums[i] < nums[i-1],则 dec++inc = 1
5)若相等,则 inc = dec = 1
6)每一步更新答案 ans = max(ans, inc, dec)

复杂度分析

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

常见陷阱

- 把“相等”误当作严格单调的一部分。
- 用了子序列思路而不是子数组(本题必须连续)。
- 方向切换时忘记重置另一条连续长度。

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

class Solution {
    public int longestMonotonicSubarray(int[] nums) {
        int n = nums.length;
        int inc = 1, dec = 1, ans = 1;

        for (int i = 1; i < n; i++) {
            if (nums[i] > nums[i - 1]) {
                inc++;
                dec = 1;
            } else if (nums[i] < nums[i - 1]) {
                dec++;
                inc = 1;
            } else {
                inc = 1;
                dec = 1;
            }
            ans = Math.max(ans, Math.max(inc, dec));
        }

        return ans;
    }
}
func longestMonotonicSubarray(nums []int) int {
    inc, dec, ans := 1, 1, 1

    for i := 1; i < len(nums); i++ {
        if nums[i] > nums[i-1] {
            inc++
            dec = 1
        } else if nums[i] < nums[i-1] {
            dec++
            inc = 1
        } else {
            inc, dec = 1, 1
        }

        if inc > ans {
            ans = inc
        }
        if dec > ans {
            ans = dec
        }
    }

    return ans
}
class Solution {
public:
    int longestMonotonicSubarray(vector<int>& nums) {
        int inc = 1, dec = 1, ans = 1;

        for (int i = 1; i < (int)nums.size(); ++i) {
            if (nums[i] > nums[i - 1]) {
                ++inc;
                dec = 1;
            } else if (nums[i] < nums[i - 1]) {
                ++dec;
                inc = 1;
            } else {
                inc = dec = 1;
            }
            ans = max(ans, max(inc, dec));
        }

        return ans;
    }
};
from typing import List

class Solution:
    def longestMonotonicSubarray(self, nums: List[int]) -> int:
        inc = dec = ans = 1

        for i in range(1, len(nums)):
            if nums[i] > nums[i - 1]:
                inc += 1
                dec = 1
            elif nums[i] < nums[i - 1]:
                dec += 1
                inc = 1
            else:
                inc = dec = 1

            ans = max(ans, inc, dec)

        return ans
var longestMonotonicSubarray = function(nums) {
  let inc = 1, dec = 1, ans = 1;

  for (let i = 1; i < nums.length; i++) {
    if (nums[i] > nums[i - 1]) {
      inc++;
      dec = 1;
    } else if (nums[i] < nums[i - 1]) {
      dec++;
      inc = 1;
    } else {
      inc = 1;
      dec = 1;
    }

    ans = Math.max(ans, inc, dec);
  }

  return ans;
};

Comments