👋
Welcome to my blog!

Monotonic Array

Decode the concept of monotonic arrays and learn to determine them with this algorithm.

Monotonic Array
array
medium

Published At

3/5/2023

Reading Time

~ 4 min read

Write a function that takes in an array of integers and returns a boolean representing whether the array is monotonic.

An array is said to be monotonic if its elements, from left to right, are entirely non-increasing or entirely non-decreasing.

Non-increasing elements aren't necessarily exclusively decreasing; they simply don't increase. Similarly, non-decreasing elements aren't necessarily exclusively increasing; they simply don't decrease.

Note that empty arrays and arrays of one element are monotonic.

Sample Input

js
array = [-1, -5, -10, -1100, -1100, -1101, -1102, -9001]
js
array = [-1, -5, -10, -1100, -1100, -1101, -1102, -9001]

Sample Output

js
true
js
true

Hints

Hint 1

You can solve this question by iterating through the input array from left to right once.

Hint 2

Try iterating through the input array from left to right, in search of two adjacent integers that can indicate whether the array is trending upward or downward. Once you've found the tentative trend of the array, at each element thereafter, compare the element to the previous one; if this comparison breaks the previously identified trend, the array isn't monotonic.

Hint 3

Alternatively, you can start by assuming that the array is both entirely non-decreasing and entirely non-increasing. As you iterate through each element, perform a check to see if you can invalidate one or both of your assumptions.

Optimal Space & Time Complexity

O(n) time | O(1) space - where n is the length of the array

Solution-1
js
function isMonotonic(array) {
  console.log(array)
  let arrLen = array.length
  
  if (arrLen <=  2) {
    return true
  }
 
  let flow = ''
  let i = 0, j = 1
  
  while (i < arrLen && j < arrLen) {
    if (flow === '') {
      if (array[i] < array[j]) {
        flow = "increasing"
      } else if (array[i] > array[j]) {
        flow = "decreasing"
      } else {
        i++
        j++
      }
    } else {
      let localFlow = ''
      if (array[i] < array[j]) {
        localFlow = "increasing"
        if (localFlow !== flow) {
          return false
        }
      } else if (array[i] > array[j]) {
        localFlow = "decreasing"
        if (localFlow !== flow) {
          return false
        }
      }
      i++
      j++
    }
  }
 
  return true
  
}
Solution-1
js
function isMonotonic(array) {
  console.log(array)
  let arrLen = array.length
  
  if (arrLen <=  2) {
    return true
  }
 
  let flow = ''
  let i = 0, j = 1
  
  while (i < arrLen && j < arrLen) {
    if (flow === '') {
      if (array[i] < array[j]) {
        flow = "increasing"
      } else if (array[i] > array[j]) {
        flow = "decreasing"
      } else {
        i++
        j++
      }
    } else {
      let localFlow = ''
      if (array[i] < array[j]) {
        localFlow = "increasing"
        if (localFlow !== flow) {
          return false
        }
      } else if (array[i] > array[j]) {
        localFlow = "decreasing"
        if (localFlow !== flow) {
          return false
        }
      }
      i++
      j++
    }
  }
 
  return true
  
}
Solution-2
js
function isMonotonic(array) {
  // Write your code here.
  if (array.length <= 2) return true
 
  let direction = array[1] - array[0]
 
  for (let i = 2; i < array.length; i++) {
    if (direction === 0) {
      direction = array[i] - array[i - 1];
      continue
    }
    if(breaksDirection(direction, array[i - 1], array[i])) {
      return false
    }
  }
  return true
}
 
function breaksDirection(direction, previousInt, currentInt) {
  const difference = currentInt - previousInt
  if (direction > 0) return difference < 0
  return difference > 0
}
Solution-2
js
function isMonotonic(array) {
  // Write your code here.
  if (array.length <= 2) return true
 
  let direction = array[1] - array[0]
 
  for (let i = 2; i < array.length; i++) {
    if (direction === 0) {
      direction = array[i] - array[i - 1];
      continue
    }
    if(breaksDirection(direction, array[i - 1], array[i])) {
      return false
    }
  }
  return true
}
 
function breaksDirection(direction, previousInt, currentInt) {
  const difference = currentInt - previousInt
  if (direction > 0) return difference < 0
  return difference > 0
}
Solution-3
js
function isMonotonic(array) {
  let isNonDecreasing = true;
  let isNonIncreasing = true;
  for(let i = 1; i < array.length; i++) {
    if (array[i] < array[i - 1]) isNonDecreasing = false
    if (array[i] > array[i - 1]) isNonIncreasing = false
  }
 
  return isNonDecreasing || isNonIncreasing;
}
Solution-3
js
function isMonotonic(array) {
  let isNonDecreasing = true;
  let isNonIncreasing = true;
  for(let i = 1; i < array.length; i++) {
    if (array[i] < array[i - 1]) isNonDecreasing = false
    if (array[i] > array[i - 1]) isNonIncreasing = false
  }
 
  return isNonDecreasing || isNonIncreasing;
}

🛠️

Do you have any questions, or simply wish to contact me privately? Don't hesitate to shoot me a DM on Twitter.

Have a wonderful day.
Abhishek 🙏

Join My Exclusive Newsletter Community

Step into a world where creativity intersects with technology. By subscribing, you'll get a front-row seat to my latest musings, full-stack development resources, and exclusive previews of future posts. Each email is a crafted experience that includes:

  • In-depth looks at my covert projects and musings to ignite your imagination.
  • Handpicked frontend development resources and current explorations, aimed at expanding your developer toolkit.
  • A monthly infusion of inspiration with my personal selection of quotes, books, and music.

Embrace the confluence of words and wonder, curated thoughtfully and sent straight to your inbox.

No fluff. Just the highest caliber of ideas.