Open In App

# Trapping Rain Water

Given an array of N non-negative integers arr[] representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.

Examples:

Input: arr[] = {2, 0, 2}
Output: 2
Explanation: The structure is like below.
We can trap 2 units of water in the middle gap. Input: arr[]   = {3, 0, 2, 0, 4}
Output: 7
Explanation: Structure is like below.
We can trap “3 units” of water between 3 and 2,
“1 unit” on top of bar 2 and “3 units” between 2 and 4. Input: arr[] = {0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1}
Output: 6
Explanation: The structure is like below.
Trap “1 unit” between first 1 and 2, “4 units” between
first 2 and 3 and “1 unit” between second last 1 and last 2 Recommended Practice

Intuition: The basic intuition of the problem is as follows:

• An element of the array can store water if there are higher bars on the left and the right.
• The amount of water to be stored in every position can be found by finding the heights of bars on the left and right sides.
• The total amount of water stored is the summation of the water stored in each index.

For example – Consider the array arr[] = {3, 0, 2, 0, 4}
Three units of water can be stored in two indexes 1 and 3, and one unit of water at index 2.
Water stored in each index = 0 + 3 + 1 + 3 + 0 = 7 Approach 1 (Brute Approach): This approach is the brute approach. The idea is to:

Traverse every array element and find the highest bars on the left and right sides. Take the smaller of two heights. The difference between the smaller height and the height of the current element is the amount of water that can be stored in this array element.

Follow the steps mentioned below to implement the idea:

• Traverse the array from start to end:
• For every element:
• Traverse the array from start to that index and find the maximum height (a) and
• Traverse the array from the current index to the end, and find the maximum height (b).
• The amount of water that will be stored in this column is min(a,b) – array[i], add this value to the total amount of water stored
• Print the total amount of water stored.

Below is the implementation of the above approach.

## C++

 `// C++ implementation of the approach`` ` `#include ``using` `namespace` `std;`` ` `// Function to return the maximum``// water that can be stored``int` `maxWater(``int` `arr[], ``int` `n)``{``    ``// To store the maximum water``    ``// that can be stored``    ``int` `res = 0;`` ` `    ``// For every element of the array``    ``for` `(``int` `i = 1; i < n - 1; i++) {`` ` `        ``// Find the maximum element on its left``        ``int` `left = arr[i];``        ``for` `(``int` `j = 0; j < i; j++)``            ``left = max(left, arr[j]);`` ` `        ``// Find the maximum element on its right``        ``int` `right = arr[i];``        ``for` `(``int` `j = i + 1; j < n; j++)``            ``right = max(right, arr[j]);`` ` `        ``// Update the maximum water``        ``res = res + (min(left, right) - arr[i]);``    ``}`` ` `    ``return` `res;``}`` ` `// Driver code``int` `main()``{``    ``int` `arr[] = { 0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1 };``    ``int` `n = ``sizeof``(arr) / ``sizeof``(arr);`` ` `    ``cout << maxWater(arr, n);`` ` `    ``return` `0;``}`

## C

 `// C code to implement the approach`` ` `#include `` ` `// Creating MACRO for finding the maximum number``#define max(x, y) (((x) > (y)) ? (x) : (y))`` ` `// Creating MACRO for finding the minimum number``#define min(x, y) (((x) < (y)) ? (x) : (y))`` ` `// Function to return the maximum``// water that can be stored``int` `maxWater(``int` `arr[], ``int` `n)``{``    ``// To store the maximum water``    ``int` `res = 0;`` ` `    ``// For every element of the array``    ``for` `(``int` `i = 0; i < n; i++) {`` ` `        ``// Find the maximum element on its left``        ``int` `left = arr[i];``        ``for` `(``int` `j = 0; j < i; j++) {``            ``left = max(left, arr[j]);``        ``}`` ` `        ``// Find the maximum element on its left``        ``int` `right = arr[i];``        ``for` `(``int` `j = i + 1; j < n; j++) {``            ``right = max(right, arr[j]);``        ``}`` ` `        ``// Update the result (maximum water)``        ``res = res + (min(left, right) - arr[i]);``    ``}`` ` `    ``// Return the maximum water``    ``return` `res;``}`` ` `// Driver code``int` `main()``{``    ``int` `arr[] = { 0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1 };``    ``int` `n = ``sizeof``(arr) / ``sizeof``(arr);``    ``printf``(``"%d"``, maxWater(arr, n));``    ``return` `0;``}`` ` `// This code is contributed by amnindersingh1414.`

## Java

 `// Java code to implement of the approach`` ` `class` `GFG {`` ` `    ``// Function to return the maximum``    ``// water that can be stored``    ``public` `static` `int` `maxWater(``int``[] arr, ``int` `n)``    ``{`` ` `        ``// To store the maximum water``        ``// that can be stored``        ``int` `res = ``0``;`` ` `        ``// For every element of the array``        ``// except first and last element``        ``for` `(``int` `i = ``1``; i < n - ``1``; i++) {`` ` `            ``// Find maximum element on its left``            ``int` `left = arr[i];``            ``for` `(``int` `j = ``0``; j < i; j++) {``                ``left = Math.max(left, arr[j]);``            ``}`` ` `            ``// Find maximum element on its right``            ``int` `right = arr[i];``            ``for` `(``int` `j = i + ``1``; j < n; j++) {``                ``right = Math.max(right, arr[j]);``            ``}`` ` `            ``// Update maximum water value``            ``res += Math.min(left, right) - arr[i];``        ``}``        ``return` `res;``    ``}`` ` `    ``// Driver code``    ``public` `static` `void` `main(String[] args)``    ``{``        ``int``[] arr = { ``0``, ``1``, ``0``, ``2``, ``1``, ``0``, ``1``, ``3``, ``2``, ``1``, ``2``, ``1` `};``        ``int` `n = arr.length;`` ` `        ``System.out.print(maxWater(arr, n));``    ``}``}`` ` `// This code is contributed by Debidutta Rath`

## Python3

 `# Python3 implementation of the approach`` ` `# Function to return the maximum``# water that can be stored``def` `maxWater(arr, n):`` ` `    ``# To store the maximum water``    ``# that can be stored``    ``res ``=` `0`` ` `    ``# For every element of the array``    ``for` `i ``in` `range``(``1``, n ``-` `1``):`` ` `        ``# Find the maximum element on its left``        ``left ``=` `arr[i]``        ``for` `j ``in` `range``(i):``            ``left ``=` `max``(left, arr[j])`` ` `        ``# Find the maximum element on its right``        ``right ``=` `arr[i]`` ` `        ``for` `j ``in` `range``(i ``+` `1``, n):``            ``right ``=` `max``(right, arr[j])`` ` `        ``# Update the maximum water``        ``res ``=` `res ``+` `(``min``(left, right) ``-` `arr[i])`` ` `    ``return` `res`` ` ` ` `# Driver code``if` `__name__ ``=``=` `"__main__"``:`` ` `    ``arr ``=` `[``0``, ``1``, ``0``, ``2``, ``1``, ``0``,``           ``1``, ``3``, ``2``, ``1``, ``2``, ``1``]``    ``n ``=` `len``(arr)`` ` `    ``print``(maxWater(arr, n))`` ` `# This code is contributed by AnkitRai01`

## C#

 `// C# implementation of the approach`` ` `using` `System;`` ` `class` `GFG {`` ` `    ``// Function to return the maximum``    ``// water that can be stored``    ``public` `static` `int` `maxWater(``int``[] arr, ``int` `n)``    ``{`` ` `        ``// To store the maximum water``        ``// that can be stored``        ``int` `res = 0;`` ` `        ``// For every element of the array``        ``// except first and last element``        ``for` `(``int` `i = 1; i < n - 1; i++) {`` ` `            ``// Find maximum element on its left``            ``int` `left = arr[i];``            ``for` `(``int` `j = 0; j < i; j++) {``                ``left = Math.Max(left, arr[j]);``            ``}`` ` `            ``// Find maximum element on its right``            ``int` `right = arr[i];``            ``for` `(``int` `j = i + 1; j < n; j++) {``                ``right = Math.Max(right, arr[j]);``            ``}`` ` `            ``// Update maximum water value``            ``res += Math.Min(left, right) - arr[i];``        ``}``        ``return` `res;``    ``}`` ` `    ``// Driver code``    ``public` `static` `void` `Main(String[] args)``    ``{``        ``int``[] arr = { 0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1 };``        ``int` `n = arr.Length;`` ` `        ``Console.Write(maxWater(arr, n));``    ``}``}`` ` `// This code is contributed by shivanisinghss2110`

## Javascript

 ``

Output

`6`

Complexity Analysis:

• Time Complexity: O(N2). There are two nested loops traversing the array.
• Space Complexity: O(1). No extra space is required.

Approach 2 (Precalculation): This is an efficient solution based on the precalculation concept:

In previous approach, for every element we needed to calculate the highest element on the left and on the right.

So, to reduce the time complexity:

• For every element we can precalculate and store the highest bar on the left and on the right (say stored in arrays left[] and right[]).
• Then iterate the array and use the precalculated values to find the amount of water stored in this index,
which is the same as ( min(left[i], right[i]) – arr[i] )

Follow the below illustration for a better understanding:

Illustration:

Consider arr[] = {3, 0, 2, 0, 4}

Therefore, left[] = {3, 3, 3, 3, 4} and right[] = {4, 4, 4, 4, 4}
Now consider iterating using i from 0 to end

For i = 0:
=> left = 3, right = 4 and arr = 3
=> Water stored = min(left, right) – arr = min(3, 4) – 3 = 3 – 3 = 0
=> Total = 0 + 0 = 0

For i = 1:
=> left = 3, right = 4 and arr = 0
=> Water stored = min(left, right) – arr = min(3, 4) – 0 = 3 – 0 = 3
=> Total = 0 + 3 = 3

For i = 2:
=> left = 3, right = 4 and arr = 2
=> Water stored = min(left, right) – arr = min(3, 4) – 2 = 3 – 2 = 1
=> Total = 3 + 1 = 4

For i = 3:
=> left = 3, right = 4 and arr = 0
=> Water stored = min(left, right) – arr = min(3, 4) – 0 = 3 – 0 = 3
=> Total = 4 + 3 = 7

For i = 4:
=> left = 4, right = 4 and arr = 4
=> Water stored = min(left, right) – arr = min(4, 4) – 4 = 4 – 4 = 0
=> Total = 7 + 0 = 7

So total rain water trapped = 7

Follow the steps mentioned below to implement the approach:

• Create two arrays left[] and right[] of size N. Create a variable (say max) to store the maximum found till a certain index during traversal.
• Run one loop from start to end:
• In each iteration update max and also assign left[i] = max.
• Run another loop from end to start:
• In each iteration update max found till now and also assign right[i] = max.
• Traverse the array from start to end.
• The amount of water that will be stored in this column is min(left[i], right[i]) – array[i]
• Add this value to the total amount of water stored
• Print the total amount of water stored.

Below is the implementation of the above approach.

## C++

 `// C++ program to find maximum amount of water that can``// be trapped within given set of bars.``#include ``using` `namespace` `std;`` ` `int` `findWater(``int` `arr[], ``int` `n)``{``    ``// left[i] contains height of tallest bar to the``    ``// left of i'th bar including itself``    ``int` `left[n];`` ` `    ``// Right [i] contains height of tallest bar to``    ``// the right of ith bar including itself``    ``int` `right[n];`` ` `    ``// Initialize result``    ``int` `water = 0;`` ` `    ``// Fill left array``    ``left = arr;``    ``for` `(``int` `i = 1; i < n; i++)``        ``left[i] = max(left[i - 1], arr[i]);`` ` `    ``// Fill right array``    ``right[n - 1] = arr[n - 1];``    ``for` `(``int` `i = n - 2; i >= 0; i--)``        ``right[i] = max(right[i + 1], arr[i]);`` ` `    ``// Calculate the accumulated water element by element``    ``// consider the amount of water on i'th bar, the``    ``// amount of water accumulated on this particular``    ``// bar will be equal to min(left[i], right[i]) - arr[i]``    ``// .``    ``for` `(``int` `i = 1; i < n - 1; i++) {``        ``int` `var = min(left[i - 1], right[i + 1]);``        ``if` `(var > arr[i]) {``            ``water += var - arr[i];``        ``}``    ``}`` ` `    ``return` `water;``}`` ` `// Driver program``int` `main()``{``    ``int` `arr[] = { 0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1 };``    ``int` `n = ``sizeof``(arr) / ``sizeof``(arr);``    ``cout << findWater(arr, n);``    ``return` `0;``}`

## C

 `// Implementation in C of the above approach`` ` `// Importing the required header files``#include `` ` `// Creating MACRO for finding the maximum number``#define max(x, y) (((x) > (y)) ? (x) : (y))`` ` `// Creating MACRO for finding the minimum number``#define min(x, y) (((x) < (y)) ? (x) : (y))`` ` `// Function to return the maximum``// water that can be stored``int` `findWater(``int` `arr[], ``int` `n)``{`` ` `    ``// left[i] contains height of tallest bar to the``    ``// left of i'th bar including itself``    ``int` `left[n];`` ` `    ``// Right [i] contains height of tallest bar to the``    ``// right of ith bar including itself``    ``int` `right[n];`` ` `    ``// Initialize result``    ``int` `water = 0;`` ` `    ``// Fill left array``    ``left = arr;``    ``for` `(``int` `i = 1; i < n; i++) {``        ``left[i] = max(left[i - 1], arr[i]);``    ``}`` ` `    ``// Fill right array``    ``right[n - 1] = arr[n - 1];``    ``for` `(``int` `i = n - 2; i >= 0; i--) {``        ``right[i] = max(right[i + 1], arr[i]);``    ``}`` ` `    ``// Calculate the accumulated water element by element``    ``// consider the amount of water on i'th bar, the``    ``// amount of water accumulated on this particular``    ``// bar will be equal to min(left[i], right[i]) - arr[i]``    ``// .``    ``for` `(``int` `i = 1; i < n - 1; i++) {``        ``int` `var = min(left[i - 1], right[i + 1]);``        ``if` `(var > arr[i]) {``            ``water += var - arr[i];``        ``}``    ``}`` ` `    ``return` `water;``}`` ` `// Driver program``int` `main()``{``    ``int` `arr[] = { 0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1 };``    ``int` `n = ``sizeof``(arr) / ``sizeof``(arr);``    ``printf``(``"%d"``, findWater(arr, n));``    ``return` `0;``}`` ` `// This code is contributed by amnindersingh1414.`

## Java

 `// Java program to find maximum amount of water that can``// be trapped within given set of bars.`` ` `class` `Test {``    ``static` `int` `arr[]``        ``= ``new` `int``[] { ``0``, ``1``, ``0``, ``2``, ``1``, ``0``, ``1``, ``3``, ``2``, ``1``, ``2``, ``1` `};`` ` `    ``// Method for maximum amount of water``    ``static` `int` `findWater(``int` `n)``    ``{``        ``// left[i] contains height of tallest bar to the``        ``// left of i'th bar including itself``        ``int` `left[] = ``new` `int``[n];`` ` `        ``// Right [i] contains height of tallest bar to``        ``// the right of ith bar including itself``        ``int` `right[] = ``new` `int``[n];`` ` `        ``// Initialize result``        ``int` `water = ``0``;`` ` `        ``// Fill left array``        ``left[``0``] = arr[``0``];``        ``for` `(``int` `i = ``1``; i < n; i++)``            ``left[i] = Math.max(left[i - ``1``], arr[i]);`` ` `        ``// Fill right array``        ``right[n - ``1``] = arr[n - ``1``];``        ``for` `(``int` `i = n - ``2``; i >= ``0``; i--)``            ``right[i] = Math.max(right[i + ``1``], arr[i]);`` ` `        ``// Calculate the accumulated water element by``        ``// element consider the amount of water on i'th bar,``        ``// the amount of water accumulated on this``        ``// particular bar will be equal to min(left[i],``        ``// right[i]) - arr[i] .``        ``for` `(``int` `i = ``0``; i < n; i++)``            ``water += Math.min(left[i], right[i]) - arr[i];`` ` `        ``return` `water;``    ``}`` ` `    ``// Driver method to test the above function``    ``public` `static` `void` `main(String[] args)``    ``{`` ` `        ``System.out.println(findWater(arr.length));``    ``}``}`

## Python3

 `# Python program to find maximum amount of water that can``# be trapped within given set of bars.`` ` ` ` `def` `findWater(arr, n):`` ` `    ``# left[i] contains height of tallest bar to the``    ``# left of i'th bar including itself``    ``left ``=` `[``0``]``*``n`` ` `    ``# Right [i] contains height of tallest bar to``    ``# the right of ith bar including itself``    ``right ``=` `[``0``]``*``n`` ` `    ``# Initialize result``    ``water ``=` `0`` ` `    ``# Fill left array``    ``left[``0``] ``=` `arr[``0``]``    ``for` `i ``in` `range``(``1``, n):``        ``left[i] ``=` `max``(left[i``-``1``], arr[i])`` ` `    ``# Fill right array``    ``right[n``-``1``] ``=` `arr[n``-``1``]``    ``for` `i ``in` `range``(n``-``2``, ``-``1``, ``-``1``):``        ``right[i] ``=` `max``(right[i ``+` `1``], arr[i])`` ` `    ``# Calculate the accumulated water element by element``    ``# consider the amount of water on i'th bar, the``    ``# amount of water accumulated on this particular``    ``# bar will be equal to min(left[i], right[i]) - arr[i] .``    ``for` `i ``in` `range``(``0``, n):``        ``water ``+``=` `min``(left[i], right[i]) ``-` `arr[i]`` ` `    ``return` `water`` ` ` ` `# Driver program``if` `__name__ ``=``=` `'__main__'``:``    ``arr ``=` `[``0``, ``1``, ``0``, ``2``, ``1``, ``0``, ``1``, ``3``, ``2``, ``1``, ``2``, ``1``]``    ``n ``=` `len``(arr)``    ``print``(findWater(arr, n))`` ` `# This code is contributed by``# Smitha Dinesh Semwal`

## C#

 `// C# program to find maximum amount of water that can``// be trapped within given set of bars.``using` `System;`` ` `class` `Test {``    ``static` `int``[] arr``        ``= ``new` `int``[] { 0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1 };`` ` `    ``// Method for maximum amount of water``    ``static` `int` `findWater(``int` `n)``    ``{``        ``// left[i] contains height of tallest bar to the``        ``// left of i'th bar including itself``        ``int``[] left = ``new` `int``[n];`` ` `        ``// Right [i] contains height of tallest bar to``        ``// the right of ith bar including itself``        ``int``[] right = ``new` `int``[n];`` ` `        ``// Initialize result``        ``int` `water = 0;`` ` `        ``// Fill left array``        ``left = arr;``        ``for` `(``int` `i = 1; i < n; i++)``            ``left[i] = Math.Max(left[i - 1], arr[i]);`` ` `        ``// Fill right array``        ``right[n - 1] = arr[n - 1];``        ``for` `(``int` `i = n - 2; i >= 0; i--)``            ``right[i] = Math.Max(right[i + 1], arr[i]);`` ` `        ``// Calculate the accumulated water element by``        ``// element consider the amount of water on i'th bar,``        ``// the amount of water accumulated on this``        ``// particular bar will be equal to min(left[i],``        ``// right[i]) - arr[i] .``        ``for` `(``int` `i = 0; i < n; i++)``            ``water += Math.Min(left[i], right[i]) - arr[i];`` ` `        ``return` `water;``    ``}`` ` `    ``// Driver method to test the above function``    ``public` `static` `void` `Main()``    ``{`` ` `        ``Console.WriteLine(findWater(arr.Length));``    ``}``}`` ` `// This code is contributed by vt_m.`

## PHP

 `= 0; ``\$i``--)``    ``\$right``[``\$i``] = max(``\$right``[``\$i` `+ 1], ``                           ``\$arr``[``\$i``]);`` ` `    ``// Calculate the accumulated``    ``// water element by element``    ``// consider the amount of ``    ``// water on i'th bar, the``    ``// amount of water accumulated``    ``// on this particular``    ``// bar will be equal to min(left[i], ``    ``// right[i]) - arr[i] .``    ``for` `(``\$i` `= 0; ``\$i` `< ``\$n``; ``\$i``++)``    ``\$water` `+= min(``\$left``[``\$i``], ``\$right``[``\$i``]) ``                             ``- ``\$arr``[``\$i``];`` ` `    ``return` `\$water``;``}`` ` `    ``// Driver program``    ``\$arr` `= ``array``(0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1);``    ``\$n` `= sizeof(``\$arr``);``    ``echo` `findWater(``\$arr``, ``\$n``);``     ` `// This code is contributed by ajit``?>`

## Javascript

 ``

Output

`6`

Complexity Analysis:

• Time Complexity: O(N). Only one traversal of the array is needed, So time Complexity is O(N).
• Space Complexity: O(N). Two extra arrays are needed, each of size N.

Approach 3 (Using Stack): The idea to solve the problem using stack is as follows:

We can use a stack to track the bars that are bounded by the higher left and right bars. This can be done using only one iteration.

• For this we will keep pushing elements in stack, until an element with higher value than the stack top is found. This denotes that there is a chance of storing position on the left side of the current element with the current bar being an end.
• So remove the smaller element on left and find the left bar (which is the current top of stack) and the amount of water stored by the left end bar and the current bar being the right end. Continue this till the stack is not empty or a higher value element is found.

Follow the below illustration for a better understanding.

Illustration:

Consider the array arr[] = {3, 0, 2, 0, 4} and an empty stack st.

For i = 0:
=> The stack is empty. So no elements with higher value on left.
=> Push the index into the stack. st = {0} [to keep track of the distance in between]

For i = 1:
=> arr is less than arr[stack top]. So arr has a higher left bound.
=> Push the index into stack. st = {0, 1}

For i = 2:
=> arr is greater than arr[stack top]. So arr is the higher right bound of current stack top.
=> Calculate the water stored in between the left and right bound of the stack top.
=> The stack top is the base height in between the left and right bound.
=> Pop the stack top. So st = {0}.
=> Water stored in between when arr and arr are the bound= {min(arr, arr) – arr} * (2 – 0 – 1) = 2.
=> arr is greater than arr Push the index into stack. st = {0, 2}.
=> Total water stored = 0 + 2 = 2.

For i = 3:
=> arr is less than arr. So arr has a higher left bound.
=> Push the index into the stack. st = {0, 2, 3}.

For i = 4:
=> arr is greater than arr[stack top]. So arr is the higher right bound of current stack top.
=> Calculate the water stored in same way as for i = 2. The base height is arr.
=> Pop the stack top. So st = {0, 2}.
=> Water stored in between when arr and arr are the bound= {min(arr, arr) – arr} * (4 – 2 – 1) = 2.
=> arr is greater than arr.
=> Pop the stack. st = {0}.
=> Water stored in between arr and arr when arr is the base height = {min(3, 4) – 2} * (4 – 0 – 1) = 3
=> arr less than arr. So pop stack. st = {}.
=> As no element left in the stack push the index. st = {4}.
=> Total water stored = 2 + 2 + 3 = 7.

So the total amount of water stored  = 7.

Follow the steps mentioned below to implement the idea:

• Loop through the indices of the bar array.
• For each bar, do the following:
• Loop while the Stack is not empty and the current bar has a height greater than the top bar of the stack,
• Store the index of the top bar in pop_height and pop it from the Stack.
• Find the distance between the left bar(current top) of the popped bar and the current bar.
• Find the minimum height between the top bar and the current bar.
• The maximum water that can be trapped is distance * min_height.
• The water trapped, including the popped bar, is (distance * min_height) – height[pop_height].
• Return the amount received as the total amount of water

Below is the implementation of the above approach.

## C++

 `// C++ implementation of the approach``#include ``using` `namespace` `std;`` ` `// Function to return the maximum``// water that can be stored``int` `maxWater(``int` `height[], ``int` `n)``{`` ` `    ``// Stores the indices of the bars``    ``stack<``int``> st;`` ` `    ``// Stores the final result``    ``int` `ans = 0;`` ` `    ``// Loop through the each bar``    ``for` `(``int` `i = 0; i < n; i++) {`` ` `        ``// Remove bars from the stack``        ``// until the condition holds``        ``while` `((!st.empty())``               ``&& (height[st.top()] < height[i])) {`` ` `            ``// Store the height of the top``            ``// and pop it.``            ``int` `pop_height = height[st.top()];``            ``st.pop();`` ` `            ``// If the stack does not have any``            ``// bars or the popped bar``            ``// has no left boundary``            ``if` `(st.empty())``                ``break``;`` ` `            ``// Get the distance between the``            ``// left and right boundary of``            ``// popped bar``            ``int` `distance = i - st.top() - 1;`` ` `            ``// Calculate the min. height``            ``int` `min_height``                ``= min(height[st.top()], height[i])``                  ``- pop_height;`` ` `            ``ans += distance * min_height;``        ``}`` ` `        ``// If the stack is either empty or``        ``// height of the current bar is less than``        ``// or equal to the top bar of stack``        ``st.push(i);``    ``}``    ``return` `ans;``}`` ` `// Driver code``int` `main()``{`` ` `    ``int` `arr[] = { 0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1 };``    ``int` `n = ``sizeof``(arr) / ``sizeof``(arr);`` ` `    ``cout << maxWater(arr, n);`` ` `    ``return` `0;``}`` ` `// The code is contributed by Soumitri Chattopadhyay`

## Java

 `import` `java.io.*;``import` `java.util.*;`` ` `// Java implementation of the approach``class` `GFG {`` ` `    ``// Function to return the maximum``    ``// water that can be stored``    ``public` `static` `int` `maxWater(``int``[] height)``    ``{``        ``// Stores the indices of the bars``        ``Stack stack = ``new` `Stack<>();`` ` `        ``// size of the array``        ``int` `n = height.length;`` ` `        ``// Stores the final result``        ``int` `ans = ``0``;`` ` `        ``// Loop through the each bar``        ``for` `(``int` `i = ``0``; i < n; i++) {`` ` `            ``// Remove bars from the stack``            ``// until the condition holds``            ``while` `((!stack.isEmpty())``                   ``&& (height[stack.peek()] < height[i])) {`` ` `                ``// store the height of the top``                ``// and pop it.``                ``int` `pop_height = height[stack.peek()];``                ``stack.pop();`` ` `                ``// If the stack does not have any``                ``// bars or the popped bar``                ``// has no left boundary``                ``if` `(stack.isEmpty())``                    ``break``;`` ` `                ``// Get the distance between the``                ``// left and right boundary of``                ``// popped bar``                ``int` `distance = i - stack.peek() - ``1``;`` ` `                ``// Calculate the min. height``                ``int` `min_height``                    ``= Math.min(height[stack.peek()],``                               ``height[i])``                      ``- pop_height;`` ` `                ``ans += distance * min_height;``            ``}`` ` `            ``// If the stack is either empty or``            ``// height of the current bar is less than``            ``// or equal to the top bar of stack``            ``stack.push(i);``        ``}`` ` `        ``return` `ans;``    ``}``    ``// Driver code``    ``public` `static` `void` `main(String[] args)``    ``{``        ``int` `arr[] = { ``0``, ``1``, ``0``, ``2``, ``1``, ``0``, ``1``, ``3``, ``2``, ``1``, ``2``, ``1` `};``        ``System.out.print(maxWater(arr));``    ``}``}`

## Python3

 `# Python implementation of the approach`` ` `# Function to return the maximum``# water that can be stored`` ` ` ` `def` `maxWater(height):`` ` `    ``# Stores the indices of the bars``    ``stack ``=` `[]`` ` `    ``# size of the array``    ``n ``=` `len``(height)`` ` `    ``# Stores the final result``    ``ans ``=` `0`` ` `    ``# Loop through the each bar``    ``for` `i ``in` `range``(n):`` ` `        ``# Remove bars from the stack``        ``# until the condition holds``        ``while``(``len``(stack) !``=` `0` `and` `(height[stack[``-``1``]] < height[i])):`` ` `            ``# store the height of the top``            ``# and pop it.``            ``pop_height ``=` `height[stack[``-``1``]]``            ``stack.pop()`` ` `            ``# If the stack does not have any``            ``# bars or the popped bar``            ``# has no left boundary``            ``if``(``len``(stack) ``=``=` `0``):``                ``break`` ` `            ``# Get the distance between the``            ``# left and right boundary of``            ``# popped bar``            ``distance ``=` `i ``-` `stack[``-``1``] ``-` `1`` ` `            ``# Calculate the min. height``            ``min_height ``=` `min``(height[stack[``-``1``]], height[i])``-``pop_height`` ` `            ``ans ``+``=` `distance ``*` `min_height`` ` `        ``# If the stack is either empty or``        ``# height of the current bar is less than``        ``# or equal to the top bar of stack``        ``stack.append(i)`` ` `    ``return` `ans`` ` ` ` `# Driver code``if` `__name__ ``=``=` `'__main__'``:``    ``arr ``=` `[``0``, ``1``, ``0``, ``2``, ``1``, ``0``, ``1``, ``3``, ``2``, ``1``, ``2``, ``1``]``    ``print``(maxWater(arr))`` ` `# This code is contributed by rag2127`

## C#

 `using` `System;``using` `System.Collections;``using` `System.Collections.Generic;`` ` `// C# implementation of the approach``class` `GFG {`` ` `    ``// Function to return the maximum``    ``// water that can be stored``    ``public` `static` `int` `maxWater(``int``[] height)``    ``{`` ` `        ``// Stores the indices of the bars``        ``Stack stack = ``new` `Stack();`` ` `        ``// size of the array``        ``int` `n = height.Length;`` ` `        ``// Stores the final result``        ``int` `ans = 0;`` ` `        ``// Loop through the each bar``        ``for` `(``int` `i = 0; i < n; i++) {`` ` `            ``// Remove bars from the stack``            ``// until the condition holds``            ``while` `((stack.Count != 0)``                   ``&& (height[(``int``)stack.Peek()]``                       ``< height[i])) {`` ` `                ``// store the height of the top``                ``// and pop it.``                ``int` `pop_height = height[(``int``)stack.Peek()];``                ``stack.Pop();`` ` `                ``// If the stack does not have any``                ``// bars or the popped bar``                ``// has no left boundary``                ``if` `(stack.Count == 0)``                    ``break``;`` ` `                ``// Get the distance between the``                ``// left and right boundary of``                ``// popped bar``                ``int` `distance = i - (``int``)stack.Peek() - 1;`` ` `                ``// Calculate the min. height``                ``int` `min_height``                    ``= Math.Min(height[(``int``)stack.Peek()],``                               ``height[i])``                      ``- pop_height;`` ` `                ``ans += distance * min_height;``            ``}`` ` `            ``// If the stack is either empty or``            ``// height of the current bar is less than``            ``// or equal to the top bar of stack``            ``stack.Push(i);``        ``}``        ``return` `ans;``    ``}`` ` `    ``// Driver code``    ``public` `static` `void` `Main()``    ``{``        ``int``[] arr = { 0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1 };``        ``Console.Write(maxWater(arr));``    ``}``}`` ` `// This code is contributed by pratham76.`

## Javascript

 ``

Output

`6`

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

Approach 4 (Horizontal scan method): The idea is as follows:

• If max_height is the height of the tallest block, then it will be the maximum possible height for any trapped rainwater.
• And if for each unit of height we find the leftmost and the rightmost boundary for that height, we can consider all the blocks in between contain that amount of water.
• But this will consider the height of the bars also. So we have to subtract that from the total water trapped.

This can be justified as follows. Say the sections for a certain height is {i1, i2}, {i2, i3}, . . ., {ik-1, ik}
So the water stored in between for a single unit of height is the difference in between the indices
= (i2 – i1 – 1) + (i3 – i2 – 1) + . . . + (ik – ik-1 -1}) = ik – i1 – (k-1) where k is the number of bars in between.

But as we are considering all the blocks in between left and right boundary, it considers all the bars also.
So the trapped water for a single unit becomes (ik – i1 + 1)

Follow the below illustration for a better understanding.

Illustration:

Consider array arr[] = {3, 0, 2, 0, 4}.
max_height = 4 and sum of all blocks = 2 + 3 + 4 = 9.

For height = 1:
=> leftmost boundary = 0 and rightmost boundary = 4.
=> All blocks in between contain 1 height of water.
=> So amount of water trapped = (4 – 0 + 1) = 5
=> Total trapped water = 0+5 = 5

For height = 2:
=> leftmost boundary = 0 and rightmost boundary = 4.
=> All blocks in between contain 2 height of water.
=> Earlier we have considered water columns with height 1. So there is increase of 1 unit in height.
=> So amount of water trapped = (4 – 0 + 1) = 5
=> Total trapped water = 5 + 5 = 10

For height = 3:
=> leftmost boundary = 0 and rightmost boundary = 4.
=> All blocks in between contain 3 height of water.
=> Earlier we have considered water columns with height 2. So there is increase of 1 unit in height.
=> So amount of water trapped = (4 – 0 + 1) = 5
=> Total trapped water = 10 + 5 = 15

For height = 4:
=> leftmost boundary = 4 and rightmost boundary = 4.
=> All blocks in between contain 4 height of water.
=> Earlier we have considered water columns with height 3. So there is increase of 1 unit in height.
=> So amount of water trapped = (4 – 4 + 1) = 1
=> Total trapped water = 15 + 1 = 16

So total water trapped  = 16 – total space taken by bars = 16 – 9 = 7.

Follow the steps mentioned below to implement the idea:

• Find the total number of blocks, i.e., the sum of the heights array, num_blocks
• Find the maximum height, max_height
• Store total water in a variable, total = 0
• Keep two pointers, left = 0 and right = N -1, to store the leftmost and the rightmost boundaries for each unit of height
• For each height, i from 1 to max_height, do the following
• Find the leftmost and the rightmost boundary for the current height.
• As mentioned earlier we can consider all the blocks in between these to have at least i unit of water.
• Add this amount of water to the total trapped water.
• After the iteration is over, subtract num_blocks from total as we have considered them as water height during calculation.

Below is the implementation of the above approach.

## C++

 `// C++ program to implement the approach``#include ``using` `namespace` `std;`` ` `int` `trappedWater(vector<``int``>& arr)``{``    ``int` `num_blocks = 0;``    ``int` `n = 0;``    ``int` `max_height = INT_MIN;`` ` `    ``// Find total blocks, max height and length of array``    ``for` `(``auto` `height : arr) {``        ``num_blocks += height;``        ``n += 1;``        ``max_height = max(max_height, height);``    ``}`` ` `    ``// Total water, left pointer and right pointer``    ``// initialized to 0 and n - 1``    ``int` `total = 0;``    ``int` `left = 0;``    ``int` `right = n - 1;`` ` `    ``for` `(``int` `i = 1; i <= max_height; i++) {`` ` `        ``// Find leftmost point greater than current row (i)``        ``while` `(arr[left] < i)``            ``left += 1;`` ` `        ``// Find rightmost point greater than current row (i)``        ``while` `(arr[right] < i)``            ``right -= 1;`` ` `        ``// water in this row = right - left  + 1``        ``total += (right - left + 1);``    ``}`` ` `    ``total -= num_blocks;``    ``return` `total;``}`` ` `// Driver code``int` `main()``{``    ``vector<``int``> arr``        ``= { 0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1 };`` ` `    ``// Function call``    ``cout << trappedWater(arr) << endl;``    ``return` `0;``}`` ` `// This code is contributed by shinjanpatra`

## Java

 `// Java program to determine how much amount of water can an``// elevation map store given in the form of an array of``// height of n points`` ` `import` `java.io.*;`` ` `class` `GFG {`` ` `    ``public` `static` `int` `trappedWater(``int` `arr[])``    ``{``        ``// To store the number of blocks``        ``int` `n = arr.length;`` ` `        ``// To store the sum of all the heights``        ``int` `num_blocks = ``0``;`` ` `        ``// To store the maximum height in the array``        ``int` `max_height = Integer.MIN_VALUE;`` ` `        ``// Compute the sum of all heights and the``        ``// maximum height given in the array``        ``for` `(``int` `i = ``0``; i < n; i++) {``            ``max_height = Math.max(max_height, arr[i]);``            ``num_blocks += arr[i];``        ``}`` ` `        ``// To store the answer and initialise``        ``// the left and right pointers``        ``int` `total = ``0``, left = ``0``, right = n - ``1``;`` ` `        ``for` `(``int` `i = ``1``; i <= max_height; i++) {`` ` `            ``// Compute the leftmost point greater than``            ``// current row (i)``            ``while` `(arr[left] < i) {``                ``left++;``            ``}`` ` `            ``// Compute the rightmost point greater than``            ``// current row (i)``            ``while` `(arr[right] < i) {``                ``right--;``            ``}`` ` `            ``// Water in this row = right - left + 1``            ``total += (right - left + ``1``);``        ``}`` ` `        ``total -= num_blocks;``        ``return` `total;``    ``}`` ` `    ``// Driver Code``    ``public` `static` `void` `main(String[] args)``    ``{``        ``int` `arr[] = { ``0``, ``1``, ``0``, ``2``, ``1``, ``0``, ``1``, ``3``, ``2``, ``1``, ``2``, ``1` `};`` ` `        ``// Function call``        ``System.out.println(trappedWater(arr));``    ``}``}`` ` `// this code is contributed by shruti456rawal`

## Python3

 `# Python code to implement the approach`` ` `def` `trappedWater(arr):``    ``num_blocks ``=` `0``    ``n ``=` `0``    ``max_height ``=` `float``(``'-inf'``)`` ` `    ``# Find total blocks, max height and length of array``    ``for` `height ``in` `arr:``        ``num_blocks ``+``=` `height``        ``n ``+``=` `1``        ``max_height ``=` `max``(max_height, height)`` ` `    ``# Total water, left pointer and right pointer ``    ``# initialized to 0 and n - 1``    ``total ``=` `0``    ``left ``=` `0``    ``right ``=` `n ``-` `1`` ` `    ``for` `i ``in` `range``(``1``, max_height``+``1``):``         ` `        ``# Find leftmost point greater than current row (i)``        ``while` `arr[left] < i:``            ``left ``+``=` `1``         ` `        ``# Find rightmost point greater than current row (i)``        ``while` `arr[right] < i:``            ``right ``-``=` `1``         ` `        ``# Water in this row = right - left + 1``        ``total ``+``=` `(right ``-` `left ``+` `1``)``     ` `    ``total ``-``=` `num_blocks``    ``return` `total`` ` `# Driver code``if` `__name__ ``=``=` `"__main__"``:``    ``arr ``=` `[``0``, ``1``, ``0``, ``2``, ``1``, ``0``, ``1``, ``3``, ``2``, ``1``, ``2``, ``1``]``    ``print``(trappedWater(arr))`

## Javascript

 ``

## C#

 `// Include namespace system``using` `System;`` ` ` ` `public` `class` `GFG``{``    ``public` `static` `int` `trappedWater(``int``[] arr)``    ``{``        ``// To store the number of blocks``        ``var` `n = arr.Length;``        ``// To store the sum of all the heights``        ``var` `num_blocks = 0;``        ``// To store the maximum height in the array``        ``var` `max_height = ``int``.MinValue;``        ``// Compute the sum of all heights and the``        ``// maximum height given in the array``        ``for` `(``int` `i = 0; i < n; i++)``        ``{``            ``max_height = Math.Max(max_height,arr[i]);``            ``num_blocks += arr[i];``        ``}``        ``// To store the answer and initialise``        ``// the left and right pointers``        ``var` `total = 0;``        ``var` `left = 0;``        ``var` `right = n - 1;``        ``for` `(``int` `i = 1; i <= max_height; i++)``        ``{``            ``// Compute the leftmost point greater than``            ``// current row (i)``            ``while` `(arr[left] < i)``            ``{``                ``left++;``            ``}``            ``// Compute the rightmost point greater than``            ``// current row (i)``            ``while` `(arr[right] < i)``            ``{``                ``right--;``            ``}``            ``// Water in this row = right - left + 1``            ``total += (right - left + 1);``        ``}``        ``total -= num_blocks;``        ``return` `total;``    ``}``    ``// Driver Code``    ``public` `static` `void` `Main(String[] args)``    ``{``        ``int``[] arr = {0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1};``        ``// Function call``        ``Console.WriteLine(GFG.trappedWater(arr));``    ``}``}`

Output

`6`

Time Complexity: O(max (max_height, N))
Space Complexity: O(1)

Approach 5 (Two Pointer Approach): The idea for this approach is as follows:

At every index, The amount of rainwater stored is the difference between the current index height and a minimum of left max height and right max-height.

Here we can use the two-pointer approach to find the minimum among the left-max and right-max of the probable outermost boundary for any index and iterate likewise.

For example:

• Say we have indices i, j and a boundary of (left, right). where i is the left pointer and j is the right pointer.
• If the minimum is arr[left], we can say that i is bounded in one side by left and no matter whatever the values are in between (i, right), the rightmost boundary of i will at  least have height arr[right] which is the probable outermost boundary for i
• So the water height of water column at index i is arr[left] – arr[i] and we can increment i then.
• Similar things happen for j also.

Follow the below illustration for a better understanding:

Illustration:

Consider ar[] = {3, 0, 2, 0, 4}
left = 0, right = 4, l_max = 0, r_max = 0.

left = 0, right = 4:
=> l_max = r_max.
=> r_max = 4, l_max = 0
=> right = 3, left = 0

left = 0, right = 3:
=> l_max < r_max.
=> r_max = 4, l_max = 3
=> right = 3, left = 1

left = 1, right = 3:
=> l_max < r_max.
=> water added = 3 – 0 = 3
=> r_max = 4, l_max = 3
=> right = 3, left = 2
=> Water trapped = 0 + 3 = 3

left = 2, right = 3:
=> l_max < r_max.
=> water added = 3 – 2 = 1
=> r_max = 4, l_max = 3
=> right = 3, left = 2
=> Water trapped = 3 + 1 = 4

left = 3, right = 3:
=> l_max < r_max.
=> water added = 3 – 0 = 3
=> r_max = 4, l_max = 3
=> right = 3, left = 4
=> Water trapped = 4 + 3 = 7

So total water trapped = 7

Follow the steps mentioned below to implement the idea:

• Take two pointers l and r. Initialize l to the starting index 0 and r to the last index N-1.
• Since l is the first element, left_max would be 0, and right_max for r would be 0.
• While l ≤ r, iterate the array. We have two possible conditions
• Condition1 : left_max <= right max
• Consider Element at index l
• Since we have traversed all elements to the left of l, left_max is known
• For the right max of l, We can say that the right max would  always be >= current r_max here
• So, min(left_max,right_max) would always equal to left_max in this case
• Increment l.
• Condition2 : left_max > right max
• Consider Element at index r
• Since we have traversed all elements to the right of r, right_max is known
• For the left max of l, We can say that the left max would  always be >= current l_max here
• So, min(left_max,right_max) would always equal to right_max in this case
• Decrement r.

Below is the implementation of the above approach.

## C++

 `// C++ implementation of the approach``#include ``using` `namespace` `std;`` ` `int` `maxWater(``int` `arr[], ``int` `n)``{ ``    ``// Indices to traverse the array``    ``int` `left = 0;``    ``int` `right = n-1;``  ` `    ``// To store Left max and right max ``    ``// for two pointers left and right``    ``int` `l_max = 0;``    ``int` `r_max = 0;``  ` `    ``// To store the total amount ``    ``// of rain water trapped``    ``int` `result = 0;``    ``while` `(left <= right)``    ``{``  ` `      ``// We need check for minimum of left ``      ``// and right max for each element``      ``if``(r_max <= l_max)``      ``{``  ` `        ``// Add the difference between ``        ``// current value and right max at index r``        ``result += max(0, r_max-arr[right]);``  ` `        ``// Update right max``        ``r_max = max(r_max, arr[right]);``  ` `        ``// Update right pointer``        ``right -= 1;``      ``}``      ``else``      ``{ ``  ` `        ``// Add the difference between ``        ``// current value and left max at index l``        ``result += max(0, l_max-arr[left]);``  ` `        ``// Update left max``        ``l_max = max(l_max, arr[left]);``  ` `        ``// Update left pointer``        ``left += 1;``      ``}``    ``}``    ``return` `result;``}`` ` `// Driver code``int` `main() {``    ``int` `arr[] = {0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1};``    ``int` `N = ``sizeof``(arr)/``sizeof``(arr);``    ``cout << maxWater(arr, N) << endl;``    ``return` `0;``}`` ` `// This code is contributed by avanitrachhadiya2155`

## Java

 `// Java implementation of the approach``import` `java.util.*;`` ` `class` `GFG {`` ` `    ``static` `int` `maxWater(``int``[] arr, ``int` `n)``    ``{`` ` `        ``// Indices to traverse the array``        ``int` `left = ``0``;``        ``int` `right = n - ``1``;`` ` `        ``// To store Left max and right max``        ``// for two pointers left and right``        ``int` `l_max = ``0``;``        ``int` `r_max = ``0``;`` ` `        ``// To store the total amount``        ``// of rain water trapped``        ``int` `result = ``0``;``        ``while` `(left <= right) {`` ` `            ``// We need check for minimum of left``            ``// and right max for each element``            ``if` `(r_max <= l_max) {`` ` `                ``// Add the difference between``                ``// current value and right max at index r``                ``result += Math.max(``0``, r_max - arr[right]);`` ` `                ``// Update right max``                ``r_max = Math.max(r_max, arr[right]);`` ` `                ``// Update right pointer``                ``right -= ``1``;``            ``}``            ``else` `{``               ` `                ``// Add the difference between``                ``// current value and left max at index l``                ``result += Math.max(``0``, l_max - arr[left]);`` ` `                ``// Update left max``                ``l_max = Math.max(l_max, arr[left]);`` ` `                ``// Update left pointer``                ``left += ``1``;``            ``}``        ``}``        ``return` `result;``    ``}`` ` `    ``// Driver code``    ``public` `static` `void` `main(String[] args)``    ``{``        ``int``[] arr = { ``0``, ``1``, ``0``, ``2``, ``1``, ``0``, ``1``, ``3``, ``2``, ``1``, ``2``, ``1` `};``        ``int` `N = arr.length;``        ``System.out.print(maxWater(arr, N));``    ``}``}`` ` `// This code is contributed by rutvik_56.`

## Python3

 `# Python3 implementation of the approach`` ` `# Function to return the maximum``# water that can be stored`` ` ` ` `def` `maxWater(arr, n):``     ` `    ``# Indices to traverse the array``    ``left ``=` `0``    ``right ``=` `n``-``1`` ` `    ``# To store Left max and right max ``    ``# for two pointers left and right``    ``l_max ``=` `0``    ``r_max ``=` `0`` ` `    ``# To store the total amount ``    ``# of rain water trapped``    ``result ``=` `0``    ``while` `(left <``=` `right):``         ` `        ``# We need check for minimum of left ``        ``# and right max for each element``        ``if` `r_max <``=` `l_max:``             ` `            ``# Add the difference between ``            ``#current value and right max at index r``            ``result ``+``=` `max``(``0``, r_max``-``arr[right])``             ` `            ``# Update right max``            ``r_max ``=` `max``(r_max, arr[right])``             ` `            ``# Update right pointer``            ``right ``-``=` `1``        ``else``:``             ` `            ``# Add the difference between ``            ``# current value and left max at index l``            ``result ``+``=` `max``(``0``, l_max``-``arr[left])``             ` `            ``# Update left max``            ``l_max ``=` `max``(l_max, arr[left])``             ` `            ``# Update left pointer``            ``left ``+``=` `1``    ``return` `result`` ` ` ` `# Driver code``if` `__name__ ``=``=` `'__main__'``:``    ``arr ``=` `[``0``, ``1``, ``0``, ``2``, ``1``, ``0``, ``1``, ``3``, ``2``, ``1``, ``2``, ``1``]``    ``N ``=` `len``(arr)``    ``print``(maxWater(arr, N))`` ` `# This code is contributed by Nikhil Chatragadda`

## C#

 `// C# implementation of the approach``using` `System;``class` `GFG {`` ` `    ``static` `int` `maxWater(``int``[] arr, ``int` `n)``    ``{`` ` `        ``// indices to traverse the array``        ``int` `left = 0;``        ``int` `right = n - 1;`` ` `        ``// To store Left max and right max``        ``// for two pointers left and right``        ``int` `l_max = 0;``        ``int` `r_max = 0;`` ` `        ``// To store the total amount``        ``// of rain water trapped``        ``int` `result = 0;``        ``while` `(left <= right) {`` ` `            ``// We need check for minimum of left``            ``// and right max for each element``            ``if` `(r_max <= l_max) {`` ` `                ``// Add the difference between``                ``// current value and right max at index r``                ``result += Math.Max(0, r_max - arr[right]);`` ` `                ``// Update right max``                ``r_max = Math.Max(r_max, arr[right]);`` ` `                ``// Update right pointer``                ``right -= 1;``            ``}``            ``else` `{`` ` `                ``// Add the difference between``                ``// current value and left max at index l``                ``result += Math.Max(0, l_max - arr[left]);`` ` `                ``// Update left max``                ``l_max = Math.Max(l_max, arr[left]);`` ` `                ``// Update left pointer``                ``left += 1;``            ``}``        ``}``        ``return` `result;``    ``}`` ` `    ``// Driver code``    ``static` `void` `Main()``    ``{``        ``int``[] arr = { 0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1 };``        ``int` `N = arr.Length;``        ``Console.WriteLine(maxWater(arr, N));``    ``}``}`` ` `// This code is contributed by divyeshrabadiya07.`

## Javascript

 ``

## C

 `// Implementation in C of the above approach`` ` `// Importing the required header files``#include // Creating MACRO for finding the maximum number`` ` `#define max(x, y)(((x) > (y)) ? (x) : (y)) // Creating MACRO for finding the minimum number ``#define min(x, y)(((x) < (y)) ? (x) : (y)) // Function to return the maximum`` ` ` ` `int` `maxWater(``int` `arr[], ``int` `n)``{``   ` `    ``// indices to traverse the array``    ``int` `left = 0;``    ``int` `right = n-1;``  ` `    ``// To store Left max and right max ``    ``// for two pointers left and right``    ``int` `l_max = 0;``    ``int` `r_max = 0;``  ` `    ``// To store the total amount ``    ``// of rain water trapped``    ``int` `result = 0;``    ``while` `(left <= right)``    ``{``  ` `      ``// We need check for minimum of left ``      ``// and right max for each element``      ``if``(r_max <= l_max)``      ``{``  ` `        ``// Add the difference between ``        ``// current value and right max at index r``        ``result += max(0, r_max-arr[right]);``  ` `        ``// Update right max``        ``r_max = max(r_max, arr[right]);``  ` `        ``// Update right pointer``        ``right -= 1;``      ``}``      ``else``      ``{ ``  ` `        ``// Add the difference between ``        ``// current value and left max at index l``        ``result += max(0, l_max-arr[left]);``  ` `        ``// Update left max``        ``l_max = max(l_max, arr[left]);``  ` `        ``// Update left pointer``        ``left += 1;``      ``}``    ``}``    ``return` `result;``}`` ` ` ` `// driver code`` ` `int` `main() {``    ``int` `arr[] = {0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1};``    ``int` `N = ``sizeof``(arr) / ``sizeof``(arr);``    ``printf``(``"%d"``, maxWater(arr, N));``    ``return` `0;``}`

Output

`6`

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

Approach 6 (Similar to linear search): Here another efficient solution has been shown.

The concept is that if there is a larger bar to the right, then the water can be retained with a height equal to the smaller bar on the left.
If there are no larger bars to the right, then start from the right. There must be a larger bar to the left now.

Follow the steps mentioned below to implement the idea:

• Loop from index 0 to the end of the given array.
• If a bar greater than or equal to the previous bar is encountered, then store the index of that bar (say prev_index).
• Keep adding the previous bar’s height minus the current (ith) bar to the final answer.
• Have a temporary variable to store the amount of water in the current segment.
• If no bar greater than or equal to the previous bar is found, then quit.
• If prev_index < size of the input array, then subtract the temporary variable from the answer, because we have considered the last segment that has no higher right bound.
• Loop from the end of the input array to prev_index.
• Find a bar greater than or equal to the previous bar (in this case, the last bar from backward).

Below is the implementation of the above approach.

## C++

 `// C++ implementation of the approach``#include ``using` `namespace` `std;`` ` `// Function to return the maximum``// water that can be stored``int` `maxWater(``int` `arr[], ``int` `n)``{``    ``int` `size = n - 1;`` ` `    ``// Let the first element be stored as``    ``// previous, we shall loop from index 1``    ``int` `prev = arr;`` ` `    ``// To store previous wall's index``    ``int` `prev_index = 0;``    ``int` `water = 0;`` ` `    ``// To store the water until a larger wall``    ``// is found, if there are no larger walls``    ``// then delete temp value from water``    ``int` `temp = 0;``    ``for` `(``int` `i = 1; i <= size; i++) {`` ` `        ``// If the current wall is taller than``        ``// the previous wall then make current``        ``// wall as the previous wall and its``        ``// index as previous wall's index``        ``// for the subsequent loops``        ``if` `(arr[i] >= prev) {``            ``prev = arr[i];``            ``prev_index = i;`` ` `            ``// Because larger or same``            ``// height wall is found``            ``temp = 0;``        ``}``        ``else` `{`` ` `            ``// Since current wall is shorter than``            ``// the previous, we subtract previous``            ``// wall's height from the current wall's``            ``// height and add it to the water``            ``water += prev - arr[i];`` ` `            ``// Store the same value in temp as well``            ``// If we dont find any larger wall then``            ``// we will subtract temp from water``            ``temp += prev - arr[i];``        ``}``    ``}`` ` `    ``// If the last wall was larger than or equal``    ``// to the previous wall then prev_index would``    ``// be equal to size of the array (last element)``    ``// If we didn't find a wall greater than or equal``    ``// to the previous wall from the left then``    ``// prev_index must be less than the index``    ``// of the last element``    ``if` `(prev_index < size) {`` ` `        ``// Temp would've stored the water collected``        ``// from previous largest wall till the end``        ``// of array if no larger wall was found then``        ``// it has excess water and remove that``        ``// from water variable``        ``water -= temp;`` ` `        ``// We start from the end of the array,``        ``// so previous should be assigned to``        ``// the last element``        ``prev = arr[size];`` ` `        ``// Loop from the end of array up to the``        ``// previous index which would contain``        ``// the largest wall from the left``        ``for` `(``int` `i = size; i >= prev_index; i--) {`` ` `            ``// Right end wall will be definitely``            ``// smaller than the 'previous index' wall``            ``if` `(arr[i] >= prev) {``                ``prev = arr[i];``            ``}``            ``else` `{``                ``water += prev - arr[i];``            ``}``        ``}``    ``}`` ` `    ``// Return the maximum water``    ``return` `water;``}`` ` `// Driver Code``int` `main()``{``    ``int` `arr[] = { 0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1 };``    ``int` `N = ``sizeof``(arr) / ``sizeof``(arr);`` ` `    ``cout << maxWater(arr, N);``    ``return` `0;``}`` ` `// This code is contributed by Debidutta Rath`

## Java

 `// Java implementation of the approach``class` `GFG {`` ` `    ``// Function to return the maximum``    ``// water that can be stored``    ``public` `static` `int` `maxWater(``int` `arr[], ``int` `n)``    ``{``        ``int` `size = n - ``1``;`` ` `        ``// Let the first element be stored as``        ``// previous, we shall loop from index 1``        ``int` `prev = arr[``0``];`` ` `        ``// To store previous wall's index``        ``int` `prev_index = ``0``;``        ``int` `water = ``0``;`` ` `        ``// To store the water until a larger wall``        ``// is found, if there are no larger walls``        ``// then delete temp value from water``        ``int` `temp = ``0``;``        ``for` `(``int` `i = ``1``; i <= size; i++) {`` ` `            ``// If the current wall is taller than``            ``// the previous wall then make current``            ``// wall as the previous wall and its``            ``// index as previous wall's index``            ``// for the subsequent loops``            ``if` `(arr[i] >= prev) {``                ``prev = arr[i];``                ``prev_index = i;`` ` `                ``// Because larger or same height wall is``                ``// found``                ``temp = ``0``;``            ``}``            ``else` `{`` ` `                ``// Since current wall is shorter than``                ``// the previous, we subtract previous``                ``// wall's height from the current wall's``                ``// height and add it to the water``                ``water += prev - arr[i];`` ` `                ``// Store the same value in temp as well``                ``// If we dont find any larger wall then``                ``// we will subtract temp from water``                ``temp += prev - arr[i];``            ``}``        ``}`` ` `        ``// If the last wall was larger than or equal``        ``// to the previous wall then prev_index would``        ``// be equal to size of the array (last element)``        ``// If we didn't find a wall greater than or equal``        ``// to the previous wall from the left then``        ``// prev_index must be less than the index``        ``// of the last element``        ``if` `(prev_index < size) {`` ` `            ``// Temp would've stored the water collected``            ``// from previous largest wall till the end``            ``// of array if no larger wall was found then``            ``// it has excess water and remove that``            ``// from 'water' var``            ``water -= temp;`` ` `            ``// We start from the end of the array, so``            ``// previous should be assigned to the last``            ``// element``            ``prev = arr[size];`` ` `            ``// Loop from the end of array up to the``            ``// 'previous index' which would contain the``            ``// "largest wall from the left"``            ``for` `(``int` `i = size; i >= prev_index; i--) {`` ` `                ``// Right end wall will be definitely smaller``                ``// than the 'previous index' wall``                ``if` `(arr[i] >= prev) {``                    ``prev = arr[i];``                ``}``                ``else` `{``                    ``water += prev - arr[i];``                ``}``            ``}``        ``}`` ` `        ``// Return the maximum water``        ``return` `water;``    ``}`` ` `    ``// Driver code``    ``public` `static` `void` `main(String[] args)``    ``{``        ``int` `arr[] = { ``0``, ``1``, ``0``, ``2``, ``1``, ``0``, ``1``, ``3``, ``2``, ``1``, ``2``, ``1` `};``        ``int` `N = arr.length;``        ``System.out.print(maxWater(arr, N));``    ``}``}`

## Python3

 `# Python3 implementation of the approach`` ` `# Function to return the maximum``# water that can be stored`` ` ` ` `def` `maxWater(arr, n):``    ``size ``=` `n ``-` `1`` ` `    ``# Let the first element be stored as``    ``# previous, we shall loop from index 1``    ``prev ``=` `arr[``0``]`` ` `    ``# To store previous wall's index``    ``prev_index ``=` `0``    ``water ``=` `0`` ` `    ``# To store the water until a larger wall``    ``# is found, if there are no larger walls``    ``# then delete temp value from water``    ``temp ``=` `0``    ``for` `i ``in` `range``(``1``, size ``+` `1``):`` ` `        ``# If the current wall is taller than``        ``# the previous wall then make current``        ``# wall as the previous wall and its``        ``# index as previous wall's index``        ``# for the subsequent loops``        ``if` `(arr[i] >``=` `prev):``            ``prev ``=` `arr[i]``            ``prev_index ``=` `i`` ` `            ``# Because larger or same height wall is found``            ``temp ``=` `0``        ``else``:`` ` `            ``# Since current wall is shorter than``            ``# the previous, we subtract previous``            ``# wall's height from the current wall's``            ``# height and add it to the water``            ``water ``+``=` `prev ``-` `arr[i]`` ` `            ``# Store the same value in temp as well``            ``# If we dont find any larger wall then``            ``# we will subtract temp from water``            ``temp ``+``=` `prev ``-` `arr[i]`` ` `    ``# If the last wall was larger than or equal``    ``# to the previous wall then prev_index would``    ``# be equal to size of the array (last element)``    ``# If we didn't find a wall greater than or equal``    ``# to the previous wall from the left then``    ``# prev_index must be less than the index``    ``# of the last element``    ``if` `(prev_index < size):`` ` `        ``# Temp would've stored the water collected``        ``# from previous largest wall till the end``        ``# of array if no larger wall was found then``        ``# it has excess water and remove that``        ``# from 'water' var``        ``water ``-``=` `temp`` ` `        ``# We start from the end of the array, so previous``        ``# should be assigned to the last element``        ``prev ``=` `arr[size]`` ` `        ``# Loop from the end of array up to the 'previous index'``        ``# which would contain the "largest wall from the left"``        ``for` `i ``in` `range``(size, prev_index ``-` `1``, ``-``1``):`` ` `            ``# Right end wall will be definitely smaller``            ``# than the 'previous index' wall``            ``if` `(arr[i] >``=` `prev):``                ``prev ``=` `arr[i]``            ``else``:``                ``water ``+``=` `prev ``-` `arr[i]`` ` `    ``# Return the maximum water``    ``return` `water`` ` ` ` `# Driver code``if` `__name__ ``=``=` `'__main__'``:``    ``arr ``=` `[``0``, ``1``, ``0``, ``2``, ``1``, ``0``, ``1``, ``3``, ``2``, ``1``, ``2``, ``1``]``    ``N ``=` `len``(arr)``    ``print``(maxWater(arr, N))`` ` `# This code is contributed by Mohit Kumar`

## C#

 `// C# implementation of the approach``using` `System;``class` `GFG {`` ` `    ``// Function to return the maximum``    ``// water that can be stored``    ``static` `int` `maxWater(``int``[] arr, ``int` `n)``    ``{``        ``int` `size = n - 1;`` ` `        ``// Let the first element be stored as``        ``// previous, we shall loop from index 1``        ``int` `prev = arr;`` ` `        ``// To store previous wall's index``        ``int` `prev_index = 0;``        ``int` `water = 0;`` ` `        ``// To store the water until a larger wall``        ``// is found, if there are no larger walls``        ``// then delete temp value from water``        ``int` `temp = 0;``        ``for` `(``int` `i = 1; i <= size; i++) {`` ` `            ``// If the current wall is taller than``            ``// the previous wall then make current``            ``// wall as the previous wall and its``            ``// index as previous wall's index``            ``// for the subsequent loops``            ``if` `(arr[i] >= prev) {``                ``prev = arr[i];``                ``prev_index = i;`` ` `                ``// Because larger or same``                ``// height wall is found``                ``temp = 0;``            ``}``            ``else` `{`` ` `                ``// Since current wall is shorter than``                ``// the previous, we subtract previous``                ``// wall's height from the current wall's``                ``// height and add it to the water``                ``water += prev - arr[i];`` ` `                ``// Store the same value in temp as well``                ``// If we dont find any larger wall then``                ``// we will subtract temp from water``                ``temp += prev - arr[i];``            ``}``        ``}`` ` `        ``// If the last wall was larger than or equal``        ``// to the previous wall then prev_index would``        ``// be equal to size of the array (last element)``        ``// If we didn't find a wall greater than or equal``        ``// to the previous wall from the left then``        ``// prev_index must be less than the index``        ``// of the last element``        ``if` `(prev_index < size) {`` ` `            ``// Temp would've stored the water collected``            ``// from previous largest wall till the end``            ``// of array if no larger wall was found then``            ``// it has excess water and remove that``            ``// from water variable``            ``water -= temp;`` ` `            ``// We start from the end of the array,``            ``// so previous should be assigned to``            ``// the last element``            ``prev = arr[size];`` ` `            ``// Loop from the end of array up to the``            ``// previous index which would contain``            ``// the largest wall from the left``            ``for` `(``int` `i = size; i >= prev_index; i--) {`` ` `                ``// Right end wall will be definitely``                ``// smaller than the 'previous index' wall``                ``if` `(arr[i] >= prev) {``                    ``prev = arr[i];``                ``}``                ``else` `{``                    ``water += prev - arr[i];``                ``}``            ``}``        ``}`` ` `        ``// Return the maximum water``        ``return` `water;``    ``}`` ` `    ``// Driver code``    ``static` `void` `Main()``    ``{``        ``int``[] arr = { 0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1 };``        ``int` `N = arr.Length;``        ``Console.WriteLine(maxWater(arr, N));``    ``}``}`` ` `// This code is contributed by divyesh072019`

## Javascript

 ``

## C

 `// Implementation in C of the above approach`` ` `// Importing the required header files``#include // Creating MACRO for finding the maximum number`` ` `#define max(x, y)                                          \``    ``(((x) > (y)) ? (x) : (y)) ``// Creating MACRO for finding``                              ``// the minimum number``#define min(x, y)                                          \``    ``(((x) < (y)) ? (x)                                     \``                 ``: (y)) ``// Function to return the maximum`` ` `// water that can be stored``int` `maxWater(``int` `arr[], ``int` `n)``{`` ` `    ``int` `size = n - 1;`` ` `    ``// Let the first element be stored as``    ``// previous, we shall loop from index 1``    ``int` `prev = arr;`` ` `    ``// To store previous wall's index``    ``int` `prev_index = 0;``    ``int` `water = 0;`` ` `    ``// To store the water until a larger wall``    ``// is found, if there are no larger walls``    ``// then delete temp value from water``    ``int` `temp = 0;`` ` `    ``for` `(``int` `i = 1; i <= size; i++) {`` ` `        ``// If the current wall is taller than``        ``// the previous wall then make current``        ``// wall as the previous wall and its``        ``// index as previous wall's index``        ``// for the subsequent loops``        ``if` `(arr[i] >= prev) {``            ``prev = arr[i];``            ``prev_index = i;`` ` `            ``// Because larger or same``            ``// height wall is found``            ``temp = 0;``        ``}``        ``else` `{`` ` `            ``// Since current wall is shorter than``            ``// the previous, we subtract previous``            ``// wall's height from the current wall's``            ``// height and add it to the water``            ``water += prev - arr[i];`` ` `            ``// Store the same value in temp as well``            ``// If we dont find any larger wall then``            ``// we will subtract temp from water``            ``temp += prev - arr[i];``        ``}``    ``}`` ` `    ``// If the last wall was larger than or equal``    ``// to the previous wall then prev_index would``    ``// be equal to size of the array (last element)``    ``// If we didn't find a wall greater than or equal``    ``// to the previous wall from the left then``    ``// prev_index must be less than the index``    ``// of the last element``    ``if` `(prev_index < size) {`` ` `        ``// Temp would've stored the water collected``        ``// from previous largest wall till the end``        ``// of array if no larger wall was found then``        ``// it has excess water and remove that``        ``// from water variable``        ``water -= temp;`` ` `        ``// We start from the end of the array,``        ``// so previous should be assigned to``        ``// the last element``        ``prev = arr[size];`` ` `        ``// Loop from the end of array up to the``        ``// previous index which would contain``        ``// the largest wall from the left``        ``for` `(``int` `i = size; i >= prev_index; i--) {`` ` `            ``// Right end wall will be definitely``            ``// smaller than the 'previous index' wall``            ``if` `(arr[i] >= prev) {``                ``prev = arr[i];``            ``}``            ``else` `{``                ``water += prev - arr[i];``            ``}``        ``}``    ``}`` ` `    ``// Return the maximum water``    ``return` `water;``}`` ` `// driver code`` ` `int` `main()``{``    ``int` `arr[] = { 0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1 };``    ``int` `N = ``sizeof``(arr) / ``sizeof``(arr);``    ``printf``(``"%d"``, maxWater(arr, N));``    ``return` `0;``}`

Output

`6`

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