# #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]`