# #9 Monotonic Array ###### tags:`Array` `Medium` ## Problem Monotonic Array 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 ```javascript array = [-1, -5, -10, -1100, -1100, -1101, -1102, -9001] ``` ### Sample Output ```javascript true ``` <br> <hr/> ## Solutions ### Official 01 ```javascript= // O(n) time | O(1) space - where n is the length of the array function isMonotonic(array) { 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; } exports.isMonotonic = isMonotonic; ``` <br> ### Official 02 ```javascript= // O(n) time | O(1) space - where n is the length of the array 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; } exports.isMonotonic = isMonotonic; ``` <br /> --- ### Everyone's :::spoiler 月 ```javascript= /* Time: O(n) -> iteration, Space: O(1) n is the length of array. */ function isMonotonic(array) { let isAsc = true, isDesc = true; if(array.length <= 1) return true; for(let i = 1; i < array.length; i++){ if(array[i] > array[i-1]){ isDesc = false; }else if(array[i] < array[i-1]){ isAsc = false; } } return isAsc || isDes } ``` ::: <br> :::spoiler 東 ```javascript= // Time O(n) | Space O(1) - n is the length of the array function isMonotonic(array) { if(array.length <= 1) return true; let isNonIncreasing = true; let isNonDecreasing = true; for(let i = 1; i < array.length; i++){ if(array[i-1] < array[i]) isNonIncreasing = false; else if(array[i-1] > array[i]) isNonDecreasing = false; } return isNonDecreasing || isNonIncreasing; } ``` - why non? ::: <br> :::spoiler Hao ```javascript= /** * Time complexity: O(n) which n stands for array.length * Space complexity: O(1) */ function isMonotonic(array) { const shouldBeAsc = (a, b) => a <= b; const shouldBeDesc = (a, b) => a >= b; let exam; for (let i = 0; i < array.length - 1 ; i += 1) { if (exam) { if (!exam(array[i], array[i + 1])) return false; } else { if (array[i] !== array[i + 1]) { if (shouldBeAsc(array[i], array[i + 1])) exam = shouldBeAsc; else exam = shouldBeDesc; } } } return true; }; ``` - `exam` is confusing in the first read. - `should` has a strong meaning. Would be more inclined using in a test.(in my opinion) ::: <br> :::spoiler YC ```javascript= /* time: O(n) - where n is the length of the array space: O(1) */ function isMonotonic(array) { if(array.length < 2) return true; const isIncreasingArray = isIncrease(array[0], array[array.length - 1]); for(let i = 0; i < array.length - 1; i++){ if(array[i] === array[i+1]){ continue; } if(isIncrease(array[i], array[i+1]) !== isIncreasingArray){ return false; } } return true; } function isIncrease(n1, n2){ return n2 - n1 > 0; } ``` ::: <br> --- ## Supplement / Discussion #### Directly assume two possibilities #### Edge case: - `"array": []` - `"array": [1]`