You are given an array of integers nums. Return the length of the longest subarray of nums which is either strictly increasing or strictly decreasing.
Note:
Example 1:
Input: nums = [1,4,3,3,2]
Output: 2Explanation: The strictly increasing subarrays of nums are [1], [2], [3], [3], [4], and [1,4].
The strictly decreasing subarrays of nums are [1], [2], [3], [3], [4], [3,2], and [4,3].
Hence, we return 2.
Example 2:
Input: nums = [3,3,3,3]
Output: 1Explanation: The strictly increasing subarrays of nums are [3], [3], [3], and [3].
The strictly decreasing subarrays of nums are [3], [3], [3], and [3].
Hence, we return 1.
Example 3:
Input: nums = [3,2,1]
Output: 3Explanation: The strictly increasing subarrays of nums are [3], [2], and [1].
The strictly decreasing subarrays of nums are [3], [2], [1], [3,2], [2,1], and [3,2,1].
Hence, we return 3.
Constraints:
1 <= nums.length <= 501 <= nums[i] <= 50Before attempting this problem, you should be comfortable with:
The straightforward approach is to check every possible starting position and see how far we can extend a monotonic subarray from there. For each starting index, we determine if the subarray is increasing or decreasing based on the first two elements, then continue as long as the pattern holds.
res = 1 to track the maximum length found.i from 0 to n-2:curLen = 1.i is increasing or decreasing.j from i+1 while the pattern continues (strictly increasing or strictly decreasing).res with the maximum of res and curLen.res.class Solution:
def longestMonotonicSubarray(self, nums: List[int]) -> int:
n = len(nums)
res = 1
for i in range(n - 1):
curLen = 1
for j in range(i + 1, n):
if nums[j] == nums[j - 1] or ((nums[i] < nums[i + 1]) != (nums[j - 1] < nums[j])):
break
curLen += 1
res = max(res, curLen)
return resWe can solve this in a single pass by tracking the current monotonic subarray's length and direction. As we scan through the array, we check if the current element continues the same pattern (increasing or decreasing). If it does, we extend the current subarray. If not, we start a new subarray with the current pair of elements.
cur = 1 (current subarray length), res = 1 (result), and increasing = 0 (direction flag).i from 1 to n-1:nums[i-1] < nums[i] (increasing):cur.cur = 2 and set increasing = 1.nums[i-1] > nums[i] (decreasing):cur.cur = 2 and set increasing = -1.cur = 1 and increasing = 0.res = max(res, cur).res.class Solution:
def longestMonotonicSubarray(self, nums: List[int]) -> int:
cur = 1
res = 1
increasing = 0
for i in range(1, len(nums)):
if nums[i - 1] < nums[i]:
if increasing > 0:
cur += 1
else:
cur = 2
increasing = 1
elif nums[i - 1] > nums[i]:
if increasing < 0:
cur += 1
else:
cur = 2
increasing = -1
else:
cur = 1
increasing = 0
res = max(res, cur)
return resA cleaner approach is to maintain two separate counters: one for the current strictly increasing subarray length and one for the current strictly decreasing subarray length. At each step, we update both counters based on the relationship between consecutive elements.
inc = 1, dec = 1 (current lengths), and res = 1 (result).i from 1 to n-1:nums[i] == nums[i-1]: reset both inc = 1 and dec = 1.nums[i] > nums[i-1]: increment inc, reset dec = 1.dec, reset inc = 1.res = max(res, inc, dec).res.class Solution:
def longestMonotonicSubarray(self, nums: List[int]) -> int:
inc = dec = 1
res = 1
for i in range(1, len(nums)):
if nums[i] == nums[i - 1]:
inc = dec = 1
elif nums[i] > nums[i - 1]:
inc, dec = inc + 1, 1
else:
inc, dec = 1, dec + 1
res = max(res, inc, dec)
return resAnother variation uses a single counter and checks if the current direction matches the direction at the start of the current subarray. By comparing the relationship between elements at the subarray's start with the relationship at the current position, we can determine if we're still following the same monotonic pattern.
curLen = 1 and res = 1.i from 1 to n-1:i-curLen differs from the direction at position i-1:curLen to 1 (if equal) or 2 (if different direction).curLen and update res = max(res, curLen).res.class Solution:
def longestMonotonicSubarray(self, nums: List[int]) -> int:
curLen = res = 1
for i in range(1, len(nums)):
if (nums[i] == nums[i - 1] or
((nums[i - curLen] < nums[i - curLen + 1]) != (nums[i - 1] < nums[i]))
):
curLen = 1 if (nums[i] == nums[i - 1]) else 2
continue
curLen += 1
res = max(res, curLen)
return resThe problem asks for strictly increasing or strictly decreasing subarrays. Equal consecutive elements (nums[i] == nums[i-1]) break both patterns. A common mistake is treating equal elements as continuing the current sequence. When you encounter equal elements, you must reset your counter to 1 because a single element is a valid subarray of length 1.
You need to find the longest subarray that is either strictly increasing OR strictly decreasing. A common error is only tracking one direction and missing the optimal answer. Either maintain two separate counters (one for increasing, one for decreasing) or use a direction flag that resets when the pattern changes.