# Longest Strictly Increasing or Strictly Decreasing Subarray
**Difficulty:** EASY
[External](https://leetcode.com/problems/longest-strictly-increasing-or-strictly-decreasing-subarray)
Canonical: https://scaleengineer.com/dsa/problems/longest-strictly-increasing-or-strictly-decreasing-subarray
**Data structures:** Array
**Companies:** [Larsen  Toubro](https://scaleengineer.com/companies/larsen-toubro)
---
## Problem
You are given an array of integers `nums`. Return _the length of the **longest** subarray of_ `nums` _which is either **strictly increasing** or **strictly decreasing**_.

**Example 1:**

**Input:** nums = \[1,4,3,3,2\]

**Output:** 2

**Explanation:**

The strictly increasing subarrays of `nums` are `[1]`, `[2]`, `[3]`, `[3]`, `[4]`, and `[1,4]`.

The strictly decreasing subarrays of `nums` are `[1]`, `[2]`, `[3]`, `[3]`, `[4]`, `[3,2]`, and `[4,3]`.

Hence, we return `2`.

**Example 2:**

**Input:** nums = \[3,3,3,3\]

**Output:** 1

**Explanation:**

The strictly increasing subarrays of `nums` are `[3]`, `[3]`, `[3]`, and `[3]`.

The strictly decreasing subarrays of `nums` are `[3]`, `[3]`, `[3]`, and `[3]`.

Hence, we return `1`.

**Example 3:**

**Input:** nums = \[3,2,1\]

**Output:** 3

**Explanation:**

The strictly increasing subarrays of `nums` are `[3]`, `[2]`, and `[1]`.

The strictly decreasing subarrays of `nums` are `[3]`, `[2]`, `[1]`, `[3,2]`, `[2,1]`, and `[3,2,1]`.

Hence, we return `3`.

**Constraints:**

* `1 <= nums.length <= 50`
* `1 <= nums[i] <= 50`

# Approaches
## Brute Force with Nested Loops
This approach iterates through each possible starting point of a subarray. For each starting point, it expands the subarray to the right, checking for both strictly increasing and strictly decreasing properties. It keeps track of the maximum length found across all possible starting points.
**Time:** O(n^2), where `n` is the length of `nums`. The outer loop runs `n` times, and for each iteration, the inner loops can run up to `n` times in the worst case (e.g., a sorted or reverse-sorted array). · **Space:** O(1) extra space. We only use a few variables to store lengths and indices, which does not depend on the input size.
**Pros:** More efficient than a naive O(n^3) approach which checks every single subarray independently.; Relatively simple to reason about and implement.
**Cons:** Not the most optimal solution as it has a quadratic time complexity.; It performs redundant computations by re-scanning parts of the array multiple times.
### Explanation
In this approach, we systematically check every possible subarray. We use a nested loop structure. The outer loop selects a starting index `i` for a subarray. The inner loops then extend this subarray from `i` to the right, one element at a time, checking for two conditions separately: if the subarray remains strictly increasing and if it remains strictly decreasing.

For each starting index `i`, we calculate the length of the longest strictly increasing subarray that begins at `i` and the length of the longest strictly decreasing subarray that also begins at `i`. We then update a global `maxLength` variable with the larger of these two lengths if they exceed the current `maxLength`. By iterating `i` through the entire array, we ensure that we have considered all possible monotonic subarrays.

```java
class Solution {
    public int longestMonotonicSubarray(int[] nums) {
        if (nums.length <= 1) {
            return nums.length;
        }
        int maxLength = 1;
        for (int i = 0; i < nums.length; i++) {
            // Check for longest increasing subarray starting at i
            int currentIncLength = 1;
            for (int j = i + 1; j < nums.length; j++) {
                if (nums[j] > nums[j - 1]) {
                    currentIncLength++;
                } else {
                    break;
                }
            }
            maxLength = Math.max(maxLength, currentIncLength);

            // Check for longest decreasing subarray starting at i
            int currentDecLength = 1;
            for (int j = i + 1; j < nums.length; j++) {
                if (nums[j] < nums[j - 1]) {
                    currentDecLength++;
                } else {
                    break;
                }
            }
            maxLength = Math.max(maxLength, currentDecLength);
        }
        return maxLength;
    }
}
```
### Algorithm
- Initialize a variable `maxLength` to 1.
- Iterate through the array with an index `i` from `0` to `n-1`, considering each element as a potential starting point of a subarray.
- For each `i`, find the length of the longest strictly increasing subarray starting at `i`.
  - Initialize `currentIncLength = 1`.
  - Iterate with index `j` from `i + 1` to `n-1`. If `nums[j] > nums[j-1]`, increment `currentIncLength`. Otherwise, break the inner loop.
  - Update `maxLength = max(maxLength, currentIncLength)`.
- For each `i`, find the length of the longest strictly decreasing subarray starting at `i`.
  - Initialize `currentDecLength = 1`.
  - Iterate with index `j` from `i + 1` to `n-1`. If `nums[j] < nums[j-1]`, increment `currentDecLength`. Otherwise, break the inner loop.
  - Update `maxLength = max(maxLength, currentDecLength)`.
- After checking all starting points `i`, return `maxLength`.

## Single Pass Iteration
This is the most efficient approach, solving the problem in a single pass. It involves iterating through the array once while keeping track of the length of the current strictly increasing subarray and the current strictly decreasing subarray ending at the current position. The overall maximum length is updated in each step.
**Time:** O(n), where `n` is the length of `nums`. We iterate through the array only once. · **Space:** O(1) extra space. We only use a constant number of variables (`maxLength`, `incLength`, `decLength`) regardless of the input array size.
**Pros:** Optimal time complexity, making it very fast even for large inputs.; Space efficient, as it only uses a constant amount of extra memory.; Elegant and concise solution.
**Cons:** May be slightly less intuitive to devise for a beginner compared to a brute-force solution.
### Explanation
The core idea is that any longest monotonic subarray must end at some index `i`. We can find the length of the longest increasing and decreasing subarrays ending at each index `i` and take the maximum of all these lengths. This can be done efficiently in one pass.

We initialize `maxLength`, `incLength`, and `decLength` to 1. `incLength` tracks the length of the current increasing subarray ending at the current element, and `decLength` tracks the current decreasing one.

We iterate from the second element (`i = 1`) and compare `nums[i]` with `nums[i-1]`. 
- If `nums[i] > nums[i-1]`, the increasing trend continues, so we increment `incLength`. The decreasing trend is broken, so we reset `decLength` to 1.
- If `nums[i] < nums[i-1]`, the decreasing trend continues, so we increment `decLength` and reset `incLength` to 1.
- If `nums[i] == nums[i-1]`, both trends are broken, so we reset both `incLength` and `decLength` to 1.

After each step, we update our global `maxLength` with the maximum value seen so far among `maxLength`, `incLength`, and `decLength`. This ensures we always have the length of the longest monotonic subarray found up to the current position.

```java
class Solution {
    public int longestMonotonicSubarray(int[] nums) {
        if (nums.length <= 1) {
            return nums.length;
        }
        
        int maxLength = 1;
        int incLength = 1;
        int decLength = 1;
        
        for (int i = 1; i < nums.length; i++) {
            if (nums[i] > nums[i - 1]) {
                incLength++;
                decLength = 1;
            } else if (nums[i] < nums[i - 1]) {
                decLength++;
                incLength = 1;
            } else {
                incLength = 1;
                decLength = 1;
            }
            maxLength = Math.max(maxLength, Math.max(incLength, decLength));
        }
        
        return maxLength;
    }
}
```
### Algorithm
- Handle the base case: if the array has 1 or fewer elements, return its length.
- Initialize `maxLength = 1`, `incLength = 1`, and `decLength = 1`.
- Iterate through the array with an index `i` from `1` to `n-1`.
- In each iteration, compare `nums[i]` with `nums[i-1]`:
  - If `nums[i] > nums[i-1]`: The increasing sequence continues. Increment `incLength` and reset `decLength` to 1.
  - If `nums[i] < nums[i-1]`: The decreasing sequence continues. Increment `decLength` and reset `incLength` to 1.
  - If `nums[i] == nums[i-1]`: Both sequences are broken. Reset both `incLength` and `decLength` to 1.
- After each comparison, update the overall maximum length: `maxLength = max(maxLength, incLength, decLength)`.
- After the loop, return `maxLength`.

# Solutions
### Java

```java
class Solution {
public
  int longestMonotonicSubarray(int[] nums) {
    int ans = 1;
    for (int i = 1, t = 1; i < nums.length; ++i) {
      if (nums[i - 1] < nums[i]) {
        ans = Math.max(ans, ++t);
      } else {
        t = 1;
      }
    }
    for (int i = 1, t = 1; i < nums.length; ++i) {
      if (nums[i - 1] > nums[i]) {
        ans = Math.max(ans, ++t);
      } else {
        t = 1;
      }
    }
    return ans;
  }
}

```

### JavaScript

```javascript
function longestMonotonicSubarray ( nums ) { const n = nums . length ; let ans = 1 ; for ( let i = 1 , t1 = 1 , t2 = 1 ; i < n ; i ++ ) { t1 = nums [ i ] > nums [ i - 1 ] ? t1 + 1 : 1 ; t2 = nums [ i ] < nums [ i - 1 ] ? t2 + 1 : 1 ; ans = Math . max ( ans , t1 , t2 ); } return ans ; }
```

### CPP

```cpp
class Solution {
public:
  int longestMonotonicSubarray(vector<int> &nums) {
    int ans = 1;
    for (int i = 1, t = 1; i < nums.size(); ++i) {
      if (nums[i - 1] < nums[i]) {
        ans = max(ans, ++t);
      } else {
        t = 1;
      }
    }
    for (int i = 1, t = 1; i < nums.size(); ++i) {
      if (nums[i - 1] > nums[i]) {
        ans = max(ans, ++t);
      } else {
        t = 1;
      }
    }
    return ans;
  }
};

```

### Python

```python
class Solution : def longestMonotonicSubarray ( self , nums : List [ int ]) -> int : ans = t = 1 for i , x in enumerate ( nums [ 1 :]): if nums [ i ] < x : t += 1 ans = max ( ans , t ) else : t = 1 t = 1 for i , x in enumerate ( nums [ 1 :]): if nums [ i ] > x : t += 1 ans = max ( ans , t ) else : t = 1 return ans
```
