Skip to content
← All posts

Monotonic Array: Single-Pass Flag Check

3 min read
leetcodeproblemeasyarrays

LeetCode Monotonic Array (problem 896) asks a deceptively simple question: given an integer array nums, return true if the array is monotonic. An array is monotonic if it is either entirely non-decreasing or entirely non-increasing. That means every element is greater than or equal to the one before it, or every element is less than or equal to the one before it.

You might think this needs two separate loops, one for each direction. It does not. A single pass with two boolean flags handles everything cleanly.

The problem

Given an array of integers, return true if the array is monotone increasing or monotone decreasing.

  • Monotone increasing: for all i, nums[i] <= nums[i+1]
  • Monotone decreasing: for all i, nums[i] >= nums[i+1]
Monotone Increasing10212233Each pair: a[i] ≤ a[i+1]Not Monotonic1031223 > 2 breaks both directions
A monotone increasing array satisfies a[i] ≤ a[i+1] for every pair. The array [1, 3, 2] has 3 > 2, which breaks increasing, and 1 < 3, which breaks decreasing.

The approach

The idea is to start by assuming the array could be both increasing and decreasing at the same time. Then you walk through each adjacent pair and update the flags based on what you see.

  • If nums[i] > nums[i+1], the array is not increasing, so set increasing = False.
  • If nums[i] < nums[i+1], the array is not decreasing, so set decreasing = False.
  • If they are equal, neither flag changes because equal pairs satisfy both directions.

After scanning every pair, if at least one flag is still True, the array is monotonic.

def isMonotonic(nums):
    increasing = True
    decreasing = True
    for i in range(len(nums) - 1):
        if nums[i] > nums[i + 1]:
            increasing = False
        if nums[i] < nums[i + 1]:
            decreasing = False
    return increasing or decreasing

Step-by-step walkthrough

Let's trace through [6, 5, 4, 4] to see how the two flags evolve.

Step 0: Initialize two flags.

increasing = Truedecreasing = True

Before scanning, assume the array could be either increasing or decreasing.

Step 1: Compare nums[0]=6 and nums[1]=5. Since 6 > 5, set increasing = False.

60514243compareincreasing:Fdecreasing:T

6 > 5 means it is not increasing. Decreasing still holds.

Step 2: Compare nums[1]=5 and nums[2]=4. Since 5 > 4, increasing stays False.

60514243compareincreasing:Fdecreasing:T

Another decrease. increasing is already False, decreasing remains True.

Step 3: Compare nums[2]=4 and nums[3]=4. Equal pair, both flags unchanged.

60514243compareincreasing:Fdecreasing:T

Equal elements satisfy both directions. No flags change.

Step 4: Return increasing OR decreasing.

increasing = Falsedecreasing = TrueResult: True

decreasing is True, so the array is monotone decreasing. Return True.

The array [6, 5, 4, 4] is monotone decreasing. The decreasing flag stayed True throughout because no pair violated the non-increasing property. Equal pairs like (4, 4) are fine in both directions.

Complexity analysis

MetricValue
TimeO(n)
SpaceO(1)

Time: You scan each adjacent pair exactly once. With n elements, that is n - 1 comparisons, which is O(n).

Space: Two boolean variables regardless of array size. No extra data structures needed.

The building blocks

1. Adjacent pair scanning

Walking through an array and comparing each element to the next one is a fundamental pattern. You will find it in problems about sorted arrays, non-decreasing subsequences, and validation checks. The key insight is that global array properties (like "is it sorted?") can be verified by checking every local pair.

for i in range(len(nums) - 1):
    # compare nums[i] with nums[i + 1]

2. Boolean flag accumulation

Instead of counting violations or storing indices, you maintain boolean flags that start as True and get set to False when a violation is found. This is a clean way to check multiple properties in a single pass. Once a flag flips to False, it stays False for the rest of the scan. The final answer combines the flags with a logical operator.

Edge cases

Single element: An array with one element is trivially monotonic. The loop body never executes, both flags remain True, and the answer is True.

All equal elements: [3, 3, 3, 3] is both non-decreasing and non-increasing. No pair triggers either flag, so both stay True.

Two elements: Any two-element array is monotonic. Either the pair is equal, increasing, or decreasing, and at least one flag will remain True.

Strictly increasing then flat: [1, 2, 3, 3] has increasing = True and decreasing = False (because of the 1 < 2 pair). The flat section at the end does not flip anything. Result is True.

From understanding to recall

This problem is easy to understand once you see it, but the two-flag pattern is surprisingly easy to forget under pressure. When you encounter a new problem that asks "does this array satisfy property X or property Y?", you want the flag accumulation technique to come to mind instantly. Spaced repetition helps you bridge the gap between understanding the solution and being able to reproduce it from scratch. By drilling the adjacent pair scan and the boolean flag pattern as separate building blocks, you build the muscle memory to recognize and apply them without hesitation.

Related posts