Monotonic Array solution and explanation
9 more videos on this problem
LeetCode 896. Monotonic Array (Algorithm Explained)Nick White · 7:16 · 11K views
Monotonic Array - Leetcode 896 - PythonNeetCodeIO · 9:45 · 11K views
LEETCODE 896 (JAVASCRIPT) | MONOTONIC ARRAYAndy Gala · 9:14 · 1K views
LeetCode 896 | Monotonic Array | Solution Explained (Java)Xavier Elon · 2:29 · 1K views
Leetcode | 896. Monotonic Array | Easy | Java SolutionDeveloper Docs · 4:51 · 1K views
LeetCode #896. Monotonic Array | Algorithm ExplainedJava2Novice · 5:10 · 953 views
Monotonic Array - LeetCode #896 | Python, JavaScript, Java, C++CodingNinja · 8:28 · 800 views
Monotonic Array - LeetCode 896 - JavaScriptAlgoJS · 5:55 · 703 views
Leetcode 896. Monotonic Array - Python tutorialCode with Carter · 9:48 · 240 views
LeetCode - 896 Monotonic Array - PythonJake LeetCode · 2:05 · 238 views
The problem
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].
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: true
Example 2:
Input: nums = [6,5,4,4] Output: true
Example 3:
Input: nums = [1,3,2] Output: false
Constraints:
1 <= nums.length <= 105-105 <= nums[i] <= 105
Approach overview
Problem Overview: You are given an integer array and must determine whether the sequence is monotonic. A monotonic array is either entirely non‑decreasing or entirely non‑increasing. Equal adjacent values are allowed, but the direction must never switch.
Approach 1: Two Separate Passes for Increasing and Decreasing (O(n) time, O(1) space)
The straightforward strategy checks both possible monotonic directions independently. First iterate through the array and verify the non‑decreasing condition: nums[i] >= nums[i-1] for every element. If any pair violates this rule, the array is not non‑decreasing. Then perform a second pass checking the non‑increasing condition nums[i] <= nums[i-1]. If either pass succeeds, the array is monotonic.
This approach keeps the logic extremely simple. Each pass performs a linear scan, comparing adjacent elements. No additional data structures are required, so space complexity stays constant. The trade‑off is that you potentially traverse the array twice, although the asymptotic complexity remains O(n). When clarity matters more than micro‑optimizations, this version is often preferred.
Approach 2: Single Pass Check for Monotonic Nature (O(n) time, O(1) space)
A more efficient implementation determines the direction during a single traversal. Track two boolean flags: one representing whether the sequence can still be non‑decreasing and another for non‑increasing. While iterating through adjacent elements, update these flags whenever a violation occurs. For example, if nums[i] < nums[i-1], the array cannot be non‑decreasing; if nums[i] > nums[i-1], it cannot be non‑increasing.
Once both flags become false, you can immediately stop because the array has already switched direction. If at least one flag survives the scan, the sequence is monotonic. This method still performs simple adjacent comparisons but reduces the logic to a single pass over the data. Time complexity remains O(n) with constant O(1) auxiliary space.
This pattern appears frequently in array traversal problems where the property of interest depends only on neighboring elements. It resembles techniques used in two pointers and simple greedy validations where you maintain state while scanning.
Recommended for interviews: The single‑pass flag approach is typically what interviewers expect. It demonstrates that you can detect monotonic direction dynamically while scanning the array once. The two‑pass method still shows solid understanding and may be easier to reason about, but the single‑pass check communicates stronger algorithmic intuition and attention to efficiency.
Approach 1: Single Pass Check for Monotonic Nature
This approach involves traversing the array and maintaining two flags: one for checking if the array elements are in increasing order and another for checking if they are in decreasing order. As we iterate through the array, we update these flags accordingly. If the array violates both conditions at any point, it is not monotonic.
def isMonotonic(nums):
increasing = True
decreasing = True
for i in range(1, len(nums)):
if nums[i] > nums[i - 1]:
decreasing = False
if nums[i] < nums[i - 1]:
increasing = False
return increasing or decreasingclass Solution {
public boolean isMonotonic(int[] nums) {
boolean increasing = true, decreasing = true;
for (int i = 1; i < nums.length; i++) {
if (nums[i] > nums[i - 1])
decreasing = false;
if (nums[i] < nums[i - 1])
increasing = false;
}
return increasing || decreasing;
}
}#include <vector>
using namespace std;
bool isMonotonic(vector<int>& nums) {
bool increasing = true, decreasing = true;
for (int i = 1; i < nums.size(); i++) {
if (nums[i] > nums[i - 1])
decreasing = false;
if (nums[i] < nums[i - 1])
increasing = false;
}
return increasing || decreasing;
}function isMonotonic(nums) {
let increasing = true, decreasing = true;
for (let i = 1; i < nums.length; i++) {
if (nums[i] > nums[i - 1])
decreasing = false;
if (nums[i] < nums[i - 1])
increasing = false;
}
return increasing || decreasing;
}#include <stdbool.h>
bool isMonotonic(int* nums, int numsSize) {
bool increasing = true, decreasing = true;
for (int i = 1; i < numsSize; i++) {
if (nums[i] > nums[i - 1])
decreasing = false;
if (nums[i] < nums[i - 1])
increasing = false;
}
return increasing || decreasing;
}public class Solution {
public bool IsMonotonic(int[] nums) {
bool increasing = true, decreasing = true;
for (int i = 1; i < nums.Length; i++) {
if (nums[i] > nums[i - 1])
decreasing = false;
if (nums[i] < nums[i - 1])
increasing = false;
}
return increasing || decreasing;
}
}Using Python, we initialize two boolean flags set to True. As we iterate through the list, we update these flags similarly based on the comparison of adjacent elements. The function returns True if the array is either entirely non-decreasing or non-increasing.
Time Complexity: O(n)
Space Complexity: O(1)
Approach 2: Two Separate Passes for Increasing and Decreasing
In this approach, we perform two separate passes to test for monotonic increase and monotonic decrease independently. The first pass checks for strictly increasing nature, and the second checks for strictly decreasing nature.
def isIncreasing(nums):
for i in range(1, len(nums)):
if nums[i] < nums[i - 1]:
return False
return True
def isDecreasing(nums):
for i in range(1, len(nums)):
if nums[i] > nums[i - 1]:
return False
return True
def isMonotonic(nums):
return isIncreasing(nums) or isDecreasing(nums)class Solution {
private boolean isIncreasing(int[] nums) {
for (int i = 1; i < nums.length; i++) {
if (nums[i] < nums[i - 1]) return false;
}
return true;
}
private boolean isDecreasing(int[] nums) {
for (int i = 1; i < nums.length; i++) {
if (nums[i] > nums[i - 1]) return false;
}
return true;
}
public boolean isMonotonic(int[] nums) {
return isIncreasing(nums) || isDecreasing(nums);
}
}#include <vector>
using namespace std;
bool isIncreasing(const vector<int>& nums) {
for (int i = 1; i < nums.size(); i++) {
if (nums[i] < nums[i - 1]) return false;
}
return true;
}
bool isDecreasing(const vector<int>& nums) {
for (int i = 1; i < nums.size(); i++) {
if (nums[i] > nums[i - 1]) return false;
}
return true;
}
bool isMonotonic(vector<int>& nums) {
return isIncreasing(nums) || isDecreasing(nums);
}function isIncreasing(nums) {
for (let i = 1; i < nums.length; i++) {
if (nums[i] < nums[i - 1]) return false;
}
return true;
}
function isDecreasing(nums) {
for (let i = 1; i < nums.length; i++) {
if (nums[i] > nums[i - 1]) return false;
}
return true;
}
function isMonotonic(nums) {
return isIncreasing(nums) || isDecreasing(nums);
}#include <stdbool.h>
bool isIncreasing(int* nums, int numsSize) {
for (int i = 1; i < numsSize; i++) {
if (nums[i] < nums[i - 1]) return false;
}
return true;
}
bool isDecreasing(int* nums, int numsSize) {
for (int i = 1; i < numsSize; i++) {
if (nums[i] > nums[i - 1]) return false;
}
return true;
}
bool isMonotonic(int* nums, int numsSize) {
return isIncreasing(nums, numsSize) || isDecreasing(nums, numsSize);
}public class Solution {
private bool IsIncreasing(int[] nums) {
for (int i = 1; i < nums.Length; i++) {
if (nums[i] < nums[i - 1]) return false;
}
return true;
}
private bool IsDecreasing(int[] nums) {
for (int i = 1; i < nums.Length; i++) {
if (nums[i] > nums[i - 1]) return false;
}
return true;
}
public bool IsMonotonic(int[] nums) {
return IsIncreasing(nums) || IsDecreasing(nums);
}
}In Python, the monotonic nature of the array is verified through two helper functions called by the main function. These functions assume responsibility for taking separate passes through the list, ensuring an accurate determination of monotonicity.
Time Complexity: O(n)
Space Complexity: O(1)
Approach 3: Single Traversal
We traverse the array, and if an increasing or decreasing situation occurs, we record it. We then check whether both increasing and decreasing situations have occurred. If both have occurred, it means that the array is not monotonic, and we return false.
Otherwise, if we reach the end of the traversal, it means that the array is monotonic, and we return true.
The time complexity is O(n), where n is the length of the array. The space complexity is O(1).
function isMonotonic(nums: number[]): boolean {
let [asc, desc] = [false, false];
for (let i = 1; i < nums.length; ++i) {
if (nums[i - 1] < nums[i]) {
asc = true;
} else if (nums[i - 1] > nums[i]) {
desc = true;
}
if (asc && desc) {
return false;
}
}
return true;
}func isMonotonic(nums []int) bool {
asc, desc := false, false
for i, x := range nums[1:] {
if nums[i] < x {
asc = true
} else if nums[i] > x {
desc = true
}
if asc && desc {
return false
}
}
return true
}impl Solution {
pub fn is_monotonic(nums: Vec<i32>) -> bool {
let mut asc = false;
let mut desc = false;
for i in 1..nums.len() {
if nums[i - 1] < nums[i] {
asc = true;
} else if nums[i - 1] > nums[i] {
desc = true;
}
if asc && desc {
return false;
}
}
true
}
}Complexity comparison
| Approach | Complexity |
|---|---|
| Single Pass Check for Monotonic Nature | Time Complexity: O(n) |
| Two Separate Passes for Increasing and Decreasing | Time Complexity: O(n) |
| Single Traversal | – |
Complexity analysis
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Two Separate Passes for Increasing and Decreasing | O(n) | O(1) | Best for readability and simple reasoning when performance differences are negligible |
| Single Pass Monotonic Check | O(n) | O(1) | Preferred interview solution since it validates monotonic direction in one traversal |
Frequently asked questions
Is Monotonic Array easy or hard?
Monotonic Array is classified as an Easy problem. The logic involves simple adjacent comparisons and constant state tracking, making it a common introductory array problem in coding interviews and online practice platforms.
Monotonic Array Python/Java solution
In both Python and Java, the solution iterates through the array once and compares nums[i] with nums[i-1]. Two boolean variables track whether the sequence can still be increasing or decreasing. This implementation runs in O(n) time and uses O(1) extra space.
How to solve Monotonic Array in O(n)?
Iterate through the array once and maintain two boolean flags: one for non-decreasing and one for non-increasing. When a pair violates either rule, update the corresponding flag. If both flags become false during traversal, return false immediately; otherwise the array is monotonic after the scan.
What is the best approach for Monotonic Array?
The best approach is a single-pass scan that tracks whether the array can still be non-decreasing or non-increasing. While iterating through adjacent elements, update two flags when violations occur. If both directions become invalid, the array is not monotonic. This method runs in O(n) time with O(1) space.
Is Monotonic Array asked at Google/Amazon/Meta?
Monotonic Array is a common easy-level screening question that appears in interview preparation sets for companies like Amazon and Google. It tests basic array traversal, edge case handling, and understanding of monotonic sequences.
What data structure is used in Monotonic Array?
The problem only requires the input array and constant auxiliary variables. No additional data structures such as stacks or hash maps are necessary because the monotonic property depends only on comparisons between adjacent elements.
What is the time complexity of Monotonic Array?
The optimal solution runs in O(n) time because it scans the array once and compares each pair of adjacent elements. Space complexity is O(1) since only a few boolean variables are used to track direction.
