 GFG App
Open App Browser
Continue

# Introduction to Monotonic Stack – Data Structure and Algorithm Tutorials

Stack is basically a restrictive array that uses LIFO Property. We use pop() and push() Operations to delete and insert elements into the stack respectively.

Stack-based problems are considered as so easy, but Monotonic Stacks are generally used to solve medium to hard-level problems.

### Explanation

A monotonic stack is a stack data structure that is used to solve problems related to finding the next greater or smaller element in an array. It is a variation of the regular stack data structure that maintains either an increasing or decreasing order of elements.

In a monotonic stack, the elements are pushed onto the stack in a way that the top element of the stack always satisfies a certain order. For example, if we want to find the next greater element in an array, we can maintain a monotonic decreasing stack. This means that if an element is pushed onto the stack, any elements that are smaller than it are popped from the stack until the top element is greater than the new element. The reason for this is that the popped elements can no longer be the next greater element for any of the remaining elements in the array.

Similarly, if we want to find the next smaller element in an array, we can maintain a monotonic increasing stack. This means that if an element is pushed onto the stack, any elements that are greater than it are popped from the stack until the top element is smaller than the new element. The reason for this is that the popped elements can no longer be the next smaller element for any of the remaining elements in the array.

Monotonic stacks can be used to solve many problems in linear time that would otherwise require quadratic time complexity. Some examples of problems that can be solved using a monotonic stack include finding the nearest smaller element on the left or right side of an array element, finding the maximum area of a histogram, and solving the sliding window maximum problem.

One of the key benefits of using a monotonic stack is that it allows us to avoid nested loops and unnecessary comparisons, which can significantly reduce the time complexity of the algorithm. Additionally, monotonic stacks can be implemented using a regular stack data structure, with only a few modifications to the push and pop operations.

In summary, a monotonic stack is a powerful data structure that can be used to efficiently solve problems related to finding the next greater or smaller element in an array. By maintaining either an increasing or decreasing order of elements, a monotonic stack allows us to avoid nested loops and unnecessary comparisons, resulting in significant improvements in time complexity.

## What is a Monotonic Stack?

Let’s understand the term Monotonic Stacks by breaking it down.

Monotonic = It is a word for mathematics functions. A function y = f(x) is monotonically increasing or decreasing when it follows the below conditions:

• As x increases, y also increases always, then it’s a monotonically increasing function.
• As x increases, y decreases always, then it’s a monotonically decreasing function.

See the below examples:

• y = 2x +5, it’s a monotonically increasing function.
• y = -(2x), it’s a monotonically decreasing function.

Similarly, A stack is called a monotonic stack if all the elements starting from the bottom of the stack is either in increasing or in decreasing order.

## Types of Monotonic Stack:

There are 2 types of monotonic stacks:

• Monotonic Increasing Stack
• Monotonic Decreasing Stack

### Monotonic Increasing Stack:

It is a stack in which the elements are in increasing order from the bottom to the top of the stack.

Example: 1, 3, 10, 15, 17

How do we achieve it?

If we pop larger elements from the stack before pushing a new element, the stack is increasing from bottom to top.

Steps to implement:

• As we need monotonically increasing stack, we should not have a smaller element at top of a bigger element.
• So Iterate the given list of elements one by one :
• Before pushing into the stack, POP all the elements till either of one condition fails:
• Stack is not empty
• Stack’s top is bigger than the element to be inserted.
• Then push the element into the stack.

See the illustration below to understand the idea:

Illustration:

Consider an array Arr[] = {1, 4, 5, 3, 12, 10}
For i = 0: stk = {1}
For i = 1: stk = {1, 4}
For i = 2: stk = {1, 4, 5}
For i = 3: stk = {1, 3}  [pop 4 and 5 as 4 > 3 and 5 > 3]
For i = 4: stk = {1, 3, 12}
For i = 5: stk = {1, 3, 10} [pop 12 as 12 > 10]

Below is the code for the above approach:

## C++

 `// C++ code to implement the approach`   `#include ` `using` `namespace` `std;`   `// Function to build Monotonic` `// increasing stack` `void` `increasingStack(``int` `arr[], ``int` `N)` `{` `    ``// Initialise stack` `    ``stack<``int``> stk;`   `    ``for` `(``int` `i = 0; i < N; i++) {`   `        ``// Either stack is empty or` `        ``// all bigger nums are popped off` `        ``while` `(stk.size() > 0 && stk.top() > arr[i]) {` `            ``stk.pop();` `        ``}` `        ``stk.push(arr[i]);` `    ``}`   `    ``int` `N2 = stk.size();` `    ``int` `ans[N2] = { 0 };` `    ``int` `j = N2 - 1;`   `    ``// Empty Stack` `    ``while` `(!stk.empty()) {` `        ``ans[j] = stk.top();` `        ``stk.pop();` `        ``j--;` `    ``}`   `    ``// Displaying the original array` `    ``cout << ``"The Array: "``;` `    ``for` `(``int` `i = 0; i < N; i++) {` `        ``cout << arr[i] << ``" "``;` `    ``}` `    ``cout << endl;`   `    ``// Displaying Monotonic increasing stack` `    ``cout << ``"The Stack: "``;` `    ``for` `(``int` `i = 0; i < N2; i++) {` `        ``cout << ans[i] << ``" "``;` `    ``}` `    ``cout << endl;` `}`   `// Driver code` `int` `main()` `{` `    ``int` `arr[] = { 1, 4, 5, 3, 12, 10 };` `    ``int` `N = ``sizeof``(arr) / ``sizeof``(arr);`   `    ``// Function Call` `    ``increasingStack(arr, N);`   `    ``return` `0;` `}` `//Code done by Balakrishnan R (rbkraj000)`

## Java

 `// Java code to implement the approach` `import` `java.io.*;` `import` `java.util.*;`   `class` `GFG {`   `  ``// Function to build Monotonic` `  ``// increasing stack` `  ``static` `void` `increasingStack(``int``[] arr, ``int` `N)` `  ``{` `    ``// Initialise stack` `    ``Stack stk = ``new` `Stack<>();`   `    ``for` `(``int` `i = ``0``; i < N; i++) {`   `      ``// Either stack is empty or` `      ``// all bigger nums are popped off` `      ``while` `(stk.size() > ``0` `&& stk.peek() > arr[i]) {` `        ``stk.pop();` `      ``}` `      ``stk.push(arr[i]);` `    ``}`   `    ``int` `N2 = stk.size();` `    ``int``[] ans = ``new` `int``[N2];` `    ``Arrays.fill(ans, ``0``);` `    ``int` `j = N2 - ``1``;`   `    ``// Empty Stack` `    ``while` `(!stk.isEmpty()) {` `      ``ans[j] = stk.peek();` `      ``stk.pop();` `      ``j--;` `    ``}`   `    ``// Displaying the original array` `    ``System.out.print(``"The Array: "``);` `    ``for` `(``int` `i = ``0``; i < N; i++) {` `      ``System.out.print(arr[i] + ``" "``);` `    ``}` `    ``System.out.println();`   `    ``// Displaying Monotonic increasing stack` `    ``System.out.print(``"The Stack: "``);` `    ``for` `(``int` `i = ``0``; i < N2; i++) {` `      ``System.out.print(ans[i] + ``" "``);` `    ``}` `    ``System.out.println();` `  ``}`   `  ``public` `static` `void` `main(String[] args)` `  ``{` `    ``int``[] arr = { ``1``, ``4``, ``5``, ``3``, ``12``, ``10` `};` `    ``int` `N = arr.length;`   `    ``// Function call` `    ``increasingStack(arr, N);` `  ``}` `}`   `// This code is contributed by lokeshmvs21.`

## Python3

 `# Python code to implement the approach`   `# Function to build Monotonic` `# increasing stack` `def` `increasingStack(arr, N):` `    ``# Initialise stack` `    ``stk``=``[]` `    `  `    ``for` `i ``in` `range``(N):` `        ``# Either stack is empty or` `        ``# all bigger nums are popped off` `        ``while``(``len``(stk) > ``0` `and` `stk[``len``(stk) ``-` `1``] > arr[i]):` `            ``stk.pop()` `        ``stk.append(arr[i])` `        `  `    ``N2 ``=` `len``(stk)` `    ``ans ``=` `[``0``]``*``N2` `    ``j ``=` `N2 ``-` `1` `    `  `    ``# Empty Stack` `    ``while``(``len``(stk) !``=` `0``):` `        ``ans[j] ``=` `stk[``len``(stk) ``-` `1``]` `        ``stk.pop()` `        ``j ``=` `j ``-` `1` `    `  `    ``# Displaying the original array` `    ``print``(``"The Array: "``,end``=``"")` `    ``for` `i ``in` `range``(N):` `        ``print``(arr[i],end``=``" "``)` `    ``print``()` `    `  `    ``# Displaying Monotonic increasing stack` `    ``print``(``"The Stack: "``,end``=``"")` `    ``for` `i ``in` `range``(N2):` `        ``print``(ans[i],end``=``" "``)` `    ``print``()` `    `  `# Driver code` `arr ``=` `[``1``, ``4``, ``5``, ``3``, ``12``, ``10``]` `N ``=` `len``(arr)`   `# Function Call` `increasingStack(arr,N)`   `# This code is contributed by Pushpesh Raj.`

## C#

 `// C# code to implement the approach`   `using` `System;` `using` `System.Collections.Generic;`   `public` `class` `GFG{`   `  ``// Function to build Monotonic` `  ``// increasing stack` `  ``static` `void` `increasingStack(``int``[] arr, ``int` `N)` `  ``{` `    ``// Initialise stack` `    ``Stack<``int``> stk = ``new` `Stack<``int``>();`   `    ``for` `(``int` `i = 0; i < N; i++)` `    ``{` `      ``// Either stack is empty or` `      ``// all bigger nums are popped off` `      ``while` `(stk.Count > 0 && stk.Peek() > arr[i])` `      ``{` `        ``stk.Pop();` `      ``}` `      ``stk.Push(arr[i]);` `    ``}`   `    ``int` `N2 = stk.Count;` `    ``int``[] ans = ``new` `int``[N2];` `    ``Array.Fill(ans, 0);` `    ``int` `j = N2 - 1;`   `    ``// Empty Stack` `    ``while` `(stk.Count > 0)` `    ``{` `      ``ans[j] = stk.Peek();` `      ``stk.Pop();` `      ``j--;` `    ``}`   `    ``// Displaying the original array` `    ``Console.Write(``"The Array: "``);` `    ``for` `(``int` `i = 0; i < N; i++)` `    ``{` `      ``Console.Write(arr[i] + ``" "``);` `    ``}` `    ``Console.WriteLine();`   `    ``// Displaying Monotonic increasing stack` `    ``Console.Write(``"The Stack: "``);` `    ``for` `(``int` `i = 0; i < N2; i++)` `    ``{` `      ``Console.Write(ans[i] + ``" "``);` `    ``}` `    ``Console.WriteLine();` `  ``}`   `  ``static` `public` `void` `Main (){`   `    ``// Code` `    ``int``[] arr = { 1, 4, 5, 3, 12, 10 };` `    ``int` `N = arr.Length;`   `    ``// Function call` `    ``increasingStack(arr, N);` `  ``}` `}`   `// This code is contributed by lokesh.`

## Javascript

 `   ``// JavaScript code for the above approach`   `   ``// Function to build Monotonic` `   ``// increasing stack` `   ``function` `increasingStack(a, N) {` `     ``// Initialise stack` `     ``let stk = [];`   `     ``for` `(let i = 0; i < N; i++) {`   `       ``// Either stack is empty or` `       ``// all bigger nums are popped off` `       ``while` `(stk.length > 0 && stk[stk.length - 1] > arr[i]) {` `         ``stk.pop();` `       ``}` `       ``stk.push(arr[i]);` `     ``}`   `     ``let N2 = stk.length;` `     ``let ans = ``new` `Array(N2);` `     ``let j = N2 - 1;`   `     ``// Empty Stack` `     ``while` `(stk.length != 0) {` `       ``ans[j] = stk[stk.length - 1];` `       ``stk.pop();` `       ``j--;` `     ``}`   `     ``// Displaying the original array` `     ``console.log(``"The Array: "``);` `     ``for` `(let i = 0; i < N; i++) {` `       ``console.log(arr[i] + ``" "``);` `     ``}` `     ``console.log(``"
"``);`   `     ``// Displaying Monotonic increasing stack` `     ``console.log(``"The Stack: "``);` `     ``for` `(let i = 0; i < N2; i++) {` `       ``console.log(ans[i] + ``" "``);` `     ``}` `     ``console.log(``"
"``);` `   ``}`   `   ``// Driver code`   `   ``let arr = [1, 4, 5, 3, 12, 10];` `   ``let N = arr.length;`   `   ``// Function Call` `   ``increasingStack(arr, N);`   `// This code is contributed by Potta Lokesh`

Output

```The Array: 1 4 5 3 12 10
The Stack: 1 3 10 ```

Time Complexity: O(N)
Auxiliary Space: O(N)

### Monotonic Decreasing Stack:

A stack is monotonically decreasing if It’s elements are in decreasing order from the bottom to the top of the stack.

Example: 17, 14, 10, 5, 1

How do we achieve it?

If we pop smaller elements from the stack before pushing a new element, the stack is decreasing from bottom to top.

Steps to implement:

• As we need monotonically decreasing stack, we should not have a bigger element at top of a smaller element.
• So Iterate the elements of the list one by one:
• Before pushing into the stack, POP all the elements till either of one condition fails:
• Stack is not empty
• Stack’s top is smaller than the element to be Inserted.
• Then push the element into the stack.

See the below illustration for a better understanding:

Illustration:

Consider an array: arr[] = {15, 17, 12, 13, 14, 10}
For i = 0: stk = {15}
For i = 1: stk = {17} [pop 15 as 15 < 17]
For i = 2: stk = {17, 12}
For i = 3: stk = {17, 13}  [pop 12 as 12 < 13]
For i = 4: stk = {17, 14}  [pop 13 as 13 < 14]
For i = 5: stk = {17, 14, 10}

Below is the implementation of the above approach:

## C++

 `// C++ code to implement the approach`   `#include ` `using` `namespace` `std;`   `// Function to find a Monotonic` `// decreasing stack` `void` `decreasingStack(``int` `arr[], ``int` `N)` `{` `    ``// Initialising Stack` `    ``stack<``int``> stk;`   `    ``for` `(``int` `i = 0; i < N; i++) {`   `        ``// Either stack empty or` `        ``// all smaller nums are popped off` `        ``while` `(stk.size() > 0 && stk.top() < arr[i]) {` `            ``stk.pop();` `        ``}` `        ``stk.push(arr[i]);` `    ``}`   `    ``int` `N2 = stk.size();` `    ``int` `ans[N2] = { 0 };` `    ``int` `j = N2 - 1;`   `    ``// Empty stack` `    ``while` `(!stk.empty()) {`   `        ``ans[j] = stk.top();` `        ``stk.pop();` `        ``j--;` `    ``}`   `    ``// Displaying the original array` `    ``cout << ``"The Array: "``;` `    ``for` `(``int` `i = 0; i < N; i++) {`   `        ``cout << arr[i] << ``" "``;` `    ``}` `    ``cout << endl;`   `    ``// Displaying Monotonic Decreasing Stack` `    ``cout << ``"The Stack: "``;` `    ``for` `(``int` `i = 0; i < N2; i++) {`   `        ``cout << ans[i] << ``" "``;` `    ``}` `    ``cout << endl;` `}`   `// Driver code` `int` `main()` `{` `    ``int` `arr[] = { 15, 17, 12, 13, 14, 10 };` `    ``int` `N = ``sizeof``(arr) / ``sizeof``(arr);`   `    ``// Function call` `    ``decreasingStack(arr, N);`   `    ``return` `0;` `}` `//Code done by Balakrishnan R (rbkraj000)`

## Java

 `// Java code to implement the approach` `import` `java.util.*;`   `public` `class` `Main {`   `    ``// Function to find a Monotonic` `    ``// decreasing stack` `    ``static` `void` `decreasingStack(``int` `arr[], ``int` `N)` `    ``{` `        ``// Initialising Stack` `        ``Stack stk = ``new` `Stack();`   `        ``for` `(``int` `i = ``0``; i < N; i++) {`   `            ``// Either stack empty or` `            ``// all smaller nums are popped off` `            ``while` `(stk.size() > ``0` `&& stk.peek() < arr[i]) {` `                ``stk.pop();` `            ``}` `            ``stk.push(arr[i]);` `        ``}`   `        ``int` `N2 = stk.size();` `        ``int` `ans[] = ``new` `int``[N2];` `        ``int` `j = N2 - ``1``;`   `        ``// Empty stack` `        ``while` `(!stk.empty()) {`   `            ``ans[j] = stk.peek();` `            ``stk.pop();` `            ``j--;` `        ``}`   `        ``// Displaying the original array` `        ``System.out.print(``"The Array: "``);` `        ``for` `(``int` `i = ``0``; i < N; i++) {`   `            ``System.out.print(arr[i] + ``" "``);` `        ``}` `        ``System.out.println();`   `        ``// Displaying Monotonic Decreasing Stack` `        ``System.out.print(``"The Stack: "``);` `        ``for` `(``int` `i = ``0``; i < N2; i++) {`   `            ``System.out.print(ans[i] + ``" "``);` `        ``}` `        ``System.out.println();` `    ``}`   `    ``// Driver code` `    ``public` `static` `void` `main(String args[])` `    ``{` `        ``int` `arr[] = { ``15``, ``17``, ``12``, ``13``, ``14``, ``10` `};` `        ``int` `N = arr.length;`   `        ``// Function call` `        ``decreasingStack(arr, N);` `    ``}` `}`

## Python3

 `# Python code to implement the approach`   `# Function to find a Monotonic` `# decreasing stack` `def` `decreasingStack(arr, N):` `    ``stack ``=` `[]` `    ``for` `i ``in` `range``(N):` `      `  `        ``# Either stack empty or` `        ``# all smaller nums are popped off` `        ``while` `len``(stack)>``0` `and` `stack[``-``1``] < arr[i]:` `            ``stack.pop()` `        ``stack.append(arr[i])` `        `  `    ``N2 ``=` `len``(stack)` `    ``ans ``=` `[``0``]``*``N2` `    ``j ``=` `N2``-``1` `    `  `    ``# Empty Stack` `    ``while` `stack !``=` `[]:` `        ``ans[j] ``=` `stack.pop()` `        ``j ``-``=` `1` `    `  `    ``# Displaying the original array` `    ``print``(``'The array: '``,end ``=` `' '``)` `    ``for` `i ``in` `range``(N):` `        ``print``(arr[i],end ``=` `' '``)` `    ``print``()` `    `  `    ``# Displaying Monotonic Decreasing Stack` `    ``print``(``'The array: '``,end ``=` `' '``)` `    ``for` `i ``in` `range``(N2):` `        ``print``(ans[i],end ``=` `' '``)` `    ``print``()` `        `  `# Driver code` `arr ``=` `[``15``, ``17``, ``12``, ``13``, ``14``, ``10``]` `N ``=` `len``(arr)`   `# Function call` `decreasingStack(arr, N)`   `# This code is contributed by hardikkhuswaha.`

## C#

 `// C# code` `using` `System;` `using` `System.Collections.Generic;`   `public` `class` `GFG {`   `  ``// Function to find a Monotonic` `  ``// decreasing stack` `  ``static` `void` `decreasingStack(``int``[] arr, ``int` `N)` `  ``{` `    ``// Initialising Stack` `    ``Stack<``int``> stk = ``new` `Stack<``int``>();`   `    ``for` `(``int` `i = 0; i < N; i++) {`   `      ``// Either stack empty or` `      ``// all smaller nums are popped off` `      ``while` `(stk.Count > 0 && stk.Peek() < arr[i]) {` `        ``stk.Pop();` `      ``}` `      ``stk.Push(arr[i]);` `    ``}`   `    ``int` `N2 = stk.Count;` `    ``int``[] ans = ``new` `int``[N2];` `    ``int` `j = N2 - 1;`   `    ``// Empty stack` `    ``while` `(stk.Count > 0) {`   `      ``ans[j] = stk.Peek();` `      ``stk.Pop();` `      ``j--;` `    ``}`   `    ``// Displaying the original array` `    ``Console.Write(``"The Array: "``);` `    ``for` `(``int` `i = 0; i < N; i++) {`   `      ``Console.Write(arr[i] + ``" "``);` `    ``}` `    ``Console.WriteLine();`   `    ``// Displaying Monotonic Decreasing Stack` `    ``Console.Write(``"The Stack: "``);` `    ``for` `(``int` `i = 0; i < N2; i++) {`   `      ``Console.Write(ans[i] + ``" "``);` `    ``}` `    ``Console.WriteLine();` `  ``}`   `  ``// Driver code` `  ``public` `static` `void` `Main(``string``[] args)` `  ``{` `    ``int``[] arr = { 15, 17, 12, 13, 14, 10 };` `    ``int` `N = arr.Length;`   `    ``// Function call` `    ``decreasingStack(arr, N);` `  ``}` `}`   `// This code is contributed by ishankhandelwals.`

## Javascript

 `// // Js code to implement the approach` `// // Function to find a Monotonic` `// // decreasing stack` `function` `decreasingStack(arr, N)` `{`   `    ``// initialising Stack` `    ``let stk = [];` `    ``for` `(let i = 0; i < N; i++) ` `    ``{` `    `  `        ``// Either stack empty or` `        ``// all smaller nums are popped off` `        ``while` `(stk.length > 0 && stk < arr[i]) {` `            ``stk.shift();` `        ``}` `        ``stk.unshift(arr[i]);` `    ``}` `    ``let N2 = stk.length;` `    ``let ans = Array(N2).fill(0);` `    ``let j = N2 - 1;` `    ``// Empty stack` `    ``while` `(stk.length != 0) {` `        ``ans[j] = stk;` `        ``stk.shift();` `        ``j--;` `    ``}` `    `  `    ``// Displaying the original array` `    ``console.log(``"The Array: "``);` `    ``for` `(let i = 0; i < N; i++) {` `        ``console.log(arr[i]);` `    ``}` `    `  `    ``// Displaying Monotonic Decreasing Stack` `    ``console.log(``"The Stack: "``);` `    ``for` `(let i = 0; i < N2; i++) {` `        ``console.log(ans[i]);` `    ``}` `}`   `// Driver code` `let arr = [15, 17, 12, 13, 14, 10];` `let N = arr.length;`   `// Function call` `decreasingStack(arr, N);`   `// This code is contributed by ishankhandelwals.`

Output

```The Array: 15 17 12 13 14 10
The Stack: 17 14 10 ```

Time Complexity: O(N)
Auxiliary Space: O(N)

## Java

 `import` `java.util.*;`   `public` `class` `Main {` `    ``public` `static` `int``[] nextGreaterElement(``int``[] nums) {` `        ``Stack stack = ``new` `Stack<>();` `        ``int``[] result = ``new` `int``[nums.length];` `        ``Arrays.fill(result, -``1``);` `        `  `        ``for` `(``int` `i = ``0``; i < nums.length; i++) {` `            ``while` `(!stack.isEmpty() && nums[i] > nums[stack.peek()]) {` `                ``int` `index = stack.pop();` `                ``result[index] = nums[i];` `            ``}` `            ``stack.push(i);` `        ``}` `        `  `        ``return` `result;` `    ``}`   `    ``public` `static` `void` `main(String[] args) {` `        ``// Example usage` `        ``int``[] nums = {``4``, ``5``, ``2``, ``25``, ``7``, ``18``};` `        ``int``[] result = nextGreaterElement(nums);` `        ``System.out.println(``"Input Array: "` `+ Arrays.toString(nums));` `        ``System.out.println(``"Next Greater Elements: "` `+ Arrays.toString(result));` `    ``}` `}`

## Python3

 `def` `next_greater_element(nums):` `    ``stack ``=` `[]` `    ``result ``=` `[``-``1``] ``*` `len``(nums)` `    `  `    ``for` `i ``in` `range``(``len``(nums)):` `        ``while` `stack ``and` `nums[i] > nums[stack[``-``1``]]:` `            ``index ``=` `stack.pop()` `            ``result[index] ``=` `nums[i]` `        ``stack.append(i)` `    `  `    ``return` `result`   `# Example usage` `nums ``=` `[``4``, ``5``, ``2``, ``25``, ``7``, ``18``]` `result ``=` `next_greater_element(nums)` `print``(``"Input Array: "``, nums)` `print``(``"Next Greater Elements: "``, result)`

Output

```Input Array:  [4, 5, 2, 25, 7, 18]
Next Greater Elements:  [5, 25, 25, -1, 18, -1]```

In this example, we are finding the next greater element for each element in the input nums array. We first initialize an empty stack and a result array of -1s. We then iterate through each element in the array using a for loop. For each element, we check if the stack is not empty and if the current element is greater than the top element of the stack. If both conditions are met, we pop the top element from the stack and set its corresponding result index to the current element. We repeat this until either the stack is empty or the top element is greater than or equal to the current element. We then push the current element index onto the stack. After we have iterated through all elements, the result array contains the next greater element for each element in the input array.

Note that this implementation assumes that all elements in the input array are distinct. If there are duplicates, we need to modify the implementation to handle them correctly.

## Applications of Monotonic Stack :

• Monotonic stack is generally used to deal with a typical problem like Next Greater Element. NGE (Find the first value on the right that is greater than the element.
• Also can be used for its varieties.
• Next Smaller Element
• Previous Greater Element
• Previous Smaller Element
• Also, we use it to get the greatest or smallest array or string by the given conditions (remaining size k/ no duplicate).
• To understand the optimization power of monotonic stacks, let’s take this example problem: Minimum Cost Tree From Leaf Values. This problem can be solved in 3 different algorithm ways, out of which the monotonic stack is the most optimized approach.
• Dynamic Programming Algorithmic Approach: O(N^3) Time O(N^2) Space
• Greedy Algorithmic Approach: O(N^2) Time O(1) Space
• Monotonic Stack Algorithmic Approach: O(N) Time O(N) Space

• We can use the extra space of a monotonic stack to reduce the time complexity.
• We can get the nearest smaller or greater element depending on the monotonic stack type, by just retrieving the stack’s top element, which is just an O(1) operation.
• The monotonic stack helps us maintain maximum and minimum elements in the range and keeps the order of elements in the range. Therefore, we don’t need to compare elements one by one again to get minima and maxima in the range. Meanwhile, because it keeps the element’s order, we only need to update the stack based on the newest added element.