896. Monotonic Array - Explanation
Description
An array is monotonic if it is either monotone increasing or monotone decreasing.
An array nums is monotone increasing if for all i <= j, nums[i] <= nums[j]. An array nums is monotone decreasing if for all i <= j, nums[i] >= nums[j].
You are given an integer array nums, return true if the given array is monotonic, or false otherwise.
Example 1:
Input: nums = [1,2,2,3]
Output: trueExample 2:
Input: nums = [6,5,4,4]
Output: trueExample 3:
Input: nums = [1,3,2]
Output: falseConstraints:
1 <= nums.length <= 100,000-100,000 <= nums[i] <= 100,000
Topics
Prerequisites
Before attempting this problem, you should be comfortable with:
- Arrays - Understanding how to iterate through arrays and access elements by index
- Comparison Operators - Using comparison operators to check relationships between adjacent elements
1. Two Pass
Intuition
An array is monotonic if it is entirely non-decreasing or entirely non-increasing. We can check each condition separately. First, scan to see if every element is greater than or equal to the previous one. If this holds, the array is monotonically increasing. If not, scan again to check if every element is less than or equal to the previous one. If either condition is satisfied, the array is monotonic.
Algorithm
- Assume the array is increasing. Iterate through and check if
nums[i] < nums[i - 1]for anyi. If found, the array is not increasing. - If the array passed the increasing check, return
true. - Otherwise, assume the array is decreasing. Iterate through and check if
nums[i] > nums[i - 1]for anyi. If found, the array is not decreasing. - Return whether the array passed the decreasing check.
class Solution:
def isMonotonic(self, nums: List[int]) -> bool:
n = len(nums)
increase = True
for i in range(1, n):
if nums[i] < nums[i - 1]:
increase = False
break
if increase:
return True
decrease = True
for i in range(1, n):
if nums[i] > nums[i - 1]:
decrease = False
break
return decreaseTime & Space Complexity
- Time complexity:
- Space complexity:
2. One Pass - I
Intuition
We can determine the expected direction by comparing the first and last elements. If the first element is less than or equal to the last, the array should be non-decreasing. Otherwise, it should be non-increasing. With the direction determined upfront, a single pass can verify whether all consecutive pairs follow the expected pattern.
Algorithm
- Compare
nums[0]andnums[n - 1]to determine the expected direction. - If
nums[0] <= nums[n - 1], the array should be non-decreasing:- Iterate through and return
falseif anynums[i] < nums[i - 1].
- Iterate through and return
- Otherwise, the array should be non-increasing:
- Iterate through and return
falseif anynums[i] > nums[i - 1].
- Iterate through and return
- If no violations are found, return
true.
Time & Space Complexity
- Time complexity:
- Space complexity:
3. One Pass - II
Intuition
Rather than deciding the direction upfront, we can track both possibilities simultaneously. We maintain two flags: one for whether the array could still be non-decreasing, and one for whether it could still be non-increasing. As we scan, any violation disqualifies that direction. At the end, if at least one flag remains true, the array is monotonic.
Algorithm
- Initialize two boolean flags:
increase = trueanddecrease = true. - Iterate through consecutive pairs
(nums[i], nums[i + 1]):- If
nums[i] > nums[i + 1], setincrease = false. - If
nums[i] < nums[i + 1], setdecrease = false.
- If
- Return
increase || decrease.
Time & Space Complexity
- Time complexity:
- Space complexity:
Common Pitfalls
Using Strict Inequality Instead of Non-Strict
A monotonic array allows equal consecutive elements (non-decreasing or non-increasing). Using strict comparisons like nums[i] > nums[i-1] instead of nums[i] >= nums[i-1] incorrectly rejects arrays like [1, 2, 2, 3] as non-monotonic. The condition should check for <= (non-decreasing) or >= (non-increasing) to properly handle equal adjacent values.
Checking Only One Direction
Arrays that are constant (all elements equal) are both non-decreasing and non-increasing. Returning false early when detecting a violation in one direction without checking the other leads to incorrect results. The array [5, 5, 5] should return true, but checking only for strictly increasing or strictly decreasing patterns would fail this case.
Sign in to join the discussion