Trapping Rain Water

06 Jul, 2022
Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.
Examples:  
Chapters
descriptions off, selected
captions settings, opens captions settings dialog
captions off, selected
English
This is a modal window.
Beginning of dialog window. Escape will cancel and close the window.
End of dialog window.
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.  See below diagram also.

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
Basic Insight: An element of the array can store water if there are higher bars on the left and right. The amount of water to be stored in every element can be found by finding the heights of bars on the left and right sides. The idea is to compute the amount of water that can be stored in every element of the array. 
Example:Consider the array {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.
For Array[] = {3, 0, 2, 0, 4} Water stored = 0 + 3 + 1 + 3 + 0 = 7  
Method 1: This is a simple solution to the above problem.
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.
Algorithm: 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 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 storedPrint the total amount of water stored.
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 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 storedPrint the total amount of water stored.
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 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.
Implementation:
C++
C
Java
Python3
C#
Javascript
// C++ implementation of the approach#include<bits/stdc++.h> using namespace std;   // Function to return the maximum// water that can be storedint 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 codeint main() {     int arr[] = {0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1};     int n = sizeof(arr)/sizeof(arr[0]);           cout << maxWater(arr, n);           return 0; }
// Implementation in C of the above approach  // Importing the required header files#include <stdio.h>  // 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 storedint 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 codeint main(){  int arr[] = {0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1};  int n = sizeof(arr) / sizeof(arr[0]);  printf("%d", maxWater(arr, n));  return 0;}  // This code is contributed by amnindersingh1414.
// Java implementation of the approachclass GFG{  // Function to return the maximum// water that can be storedpublic 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 codepublic 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 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# implementation of the approachusing System;   class GFG{  // Function to return the maximum// water that can be storedpublic 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 codepublic 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
<script>      // Javascript implementation of the approach          // Function to return the maximum    // water that can be stored    function maxWater(arr, n)    {          // To store the maximum water        // that can be stored        let res = 0;          // For every element of the array        // except first and last element        for(let i = 1; i < n - 1; i++)        {              // Find maximum element on its left            let left = arr[i];            for(let j = 0; j < i; j++)            {                left = Math.max(left, arr[j]);            }              // Find maximum element on its right            let right = arr[i];            for(let 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;    }          let arr = [ 0, 1, 0, 2, 1, 0,                1, 3, 2, 1, 2, 1 ];    let n = arr.length;       document.write(maxWater(arr,n));      </script>
6
Complexity Analysis: Time Complexity: O(n2). There are two nested loops traversing the array, So the time Complexity is O(n2).Space Complexity: O(1). No extra space is required.
Time Complexity: O(n2). There are two nested loops traversing the array, So the time Complexity is O(n2).
Space Complexity: O(1). No extra space is required.
Method 2: This is an efficient solution to the above problem.
Approach: In the previous solution, to find the highest bar on the left and right, array traversal is needed, which reduces the efficiency of the solution. To make this efficient, one must pre-compute the highest bar on the left and right of every bar in linear time. Then use these pre-computed values to find the amount of water in every array element.
Algorithm: Create two arrays left and right of size n. create a variable max_ = INT_MIN.Run one loop from start to end. In each iteration update max_ as max_ = max(max_, arr[i]) and also assign left[i] = max_Update max_ = INT_MIN.Run another loop from end to start. In each iteration update max_ as max_ = max(max_, arr[i]) 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(a,b) – array[i],(where a = left[i] and b = right[i]) add this value to total amount of water storedPrint the total amount of water stored.
Create two arrays left and right of size n. create a variable max_ = INT_MIN.Run one loop from start to end. In each iteration update max_ as max_ = max(max_, arr[i]) and also assign left[i] = max_Update max_ = INT_MIN.Run another loop from end to start. In each iteration update max_ as max_ = max(max_, arr[i]) 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(a,b) – array[i],(where a = left[i] and b = right[i]) add this value to total amount of water storedPrint the total amount of water stored.
Create two arrays left and right of size n. create a variable max_ = INT_MIN.
Run one loop from start to end. In each iteration update max_ as max_ = max(max_, arr[i]) and also assign left[i] = max_
Update max_ = INT_MIN.
Run another loop from end to start. In each iteration update max_ as max_ = max(max_, arr[i]) 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(a,b) – array[i],(where a = left[i] and b = right[i]) add this value to total amount of water stored
Print the total amount of water stored.
Implementation:
C++
C
Java
Python3
C#
PHP
Javascript
// C++ program to find maximum amount of water that can// be trapped within given set of bars.#include <bits/stdc++.h>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[0] = arr[0];    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 programint main(){    int arr[] = { 0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1 };    int n = sizeof(arr) / sizeof(arr[0]);    cout << "Maximum water that can be accumulated is "         << findWater(arr, n);    return 0;}
// Implementation in C of the above approach  // Importing the required header files#include <stdio.h>  // 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 storedint 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[0] = arr[0];    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 programint main(){    int arr[] = {0,1,0,2,1,0,1,3,2,1,2,1};    int n = sizeof(arr)/sizeof(arr[0]);    printf("Maximum water that can be accumulated is %d", findWater(arr, n));    return 0;}    // This code is contributed by amnindersingh1414.
// 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("Maximum water that can be accumulated is " + findWater(arr.length));    }}
# 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  arr = [0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1]n = len(arr)print("Maximum water that can be accumulated is", findWater(arr, n))  # This code is contributed by# Smitha Dinesh Semwal
// 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[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()    {          Console.WriteLine("Maximum water that can be accumulated is " + findWater(arr.Length));    }}  // This code is contributed by vt_m.
<?php// PHP program to find maximum// amount of water that can// be trapped within given set of bars.  function findWater($arr, $n){          // left[i] contains height of    // tallest bar to the    // left of i'th bar including     // itself       // Right [i] contains height    // of tallest bar to the right     // of ith bar including itself    // $right[$n];      // Initialize result    $water = 0;      // Fill left array    $left[0] = $arr[0];    for ($i = 1; $i < $n; $i++)    $left[$i] = max($left[$i - 1],                        $arr[$i]);      // Fill right array    $right[$n - 1] = $arr[$n - 1];    for ($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 ($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 "Maximum water that can be accumulated is ",        findWater($arr, $n);      // This code is contributed by ajit?>
<script>// Javascript program to find maximum amount of water that can// be trapped within given set of bars.          let arr = [ 0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1 ];          // Method for maximum amount of water    function findWater(n)    {              // left[i] contains height of tallest bar to the        // left of i'th bar including itself        let left = new Array(n);           // Right [i] contains height of tallest bar to        // the right of ith bar including itself        let right = new Array(n);           // Initialize result        let water = 0;           // Fill left array        left[0] = arr[0];        for (let i = 1; i < n; i++)            left[i] = Math.max(left[i - 1], arr[i]);           // Fill right array        right[n - 1] = arr[n - 1];        for (let 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 (let i = 0; i < n; i++)            water += Math.min(left[i], right[i]) - arr[i];           return water;    }          // Driver method to test the above function    document.write("Maximum water that can be accumulated is " + findWater(arr.length));      // This code is contributed by unknown2108</script>
Maximum water that can be accumulated is 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.
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.
Space Optimization for the above Solution: 
Instead of maintaining two arrays of size n for storing the left and a right max of each element, maintain two variables to store the maximum till that point. Since water trapped at any element = min(max_left, max_right) – arr[i]. Calculate water trapped on smaller elements out of A[lo] and A[hi] first, and move the pointers till lo doesn’t cross hi.
Implementation:
C++
Java
Python3
C#
PHP
Javascript
C
// C++ program to find maximum amount of water that can// be trapped within given set of bars.// Space Complexity : O(1)  #include <iostream>using namespace std;  int findWater(int arr[], int n){    // initialize output    int result = 0;      // maximum element on left and right    int left_max = 0, right_max = 0;      // indices to traverse the array    int lo = 0, hi = n - 1;      while (lo <= hi) {        if (arr[lo] < arr[hi]) {            if (arr[lo] > left_max)                // update max in left                left_max = arr[lo];            else                // water on curr element = max - curr                result += left_max - arr[lo];            lo++;        }        else {            if (arr[hi] > right_max)                // update right maximum                right_max = arr[hi];            else                result += right_max - arr[hi];            hi--;        }    }      return result;}  int main(){    int arr[] = { 0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1 };    int n = sizeof(arr) / sizeof(arr[0]);    cout << "Maximum water that can be accumulated is "         << findWater(arr, n);}  // This code is contributed by Aditi Sharma
// JAVA Code For Trapping Rain Waterimport java.util.*;  class GFG {      static int findWater(int arr[], int n)    {        // initialize output        int result = 0;          // maximum element on left and right        int left_max = 0, right_max = 0;          // indices to traverse the array        int lo = 0, hi = n - 1;          while (lo <= hi) {            if (arr[lo] < arr[hi]) {                if (arr[lo] > left_max)                      // update max in left                    left_max = arr[lo];                else                      // water on curr element =                    // max - curr                    result += left_max - arr[lo];                lo++;            }            else {                if (arr[hi] > right_max)                      // update right maximum                    right_max = arr[hi];                  else                    result += right_max - arr[hi];                hi--;            }        }          return result;    }      /* Driver program to test above function */    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.println("Maximum water that "                           + "can be accumulated is "                           + findWater(arr, n));    }}// This code is contributed by Arnav Kr. Mandal.
# Python program to find# maximum amount of water that can# be trapped within given set of bars.# Space Complexity : O(1)  def findWater(arr, n):      # initialize output    result = 0           # maximum element on left and right    left_max = 0    right_max = 0           # indices to traverse the array    lo = 0    hi = n-1           while(lo <= hi):               if(arr[lo] < arr[hi]):                      if(arr[lo] > left_max):                  # update max in left                left_max = arr[lo]            else:                  # water on curr element = max - curr                result += left_max - arr[lo]            lo+= 1                  else:                      if(arr[hi] > right_max):                # update right maximum                right_max = arr[hi]            else:                result += right_max - arr[hi]            hi-= 1              return result   # Driver program  arr = [0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1]n = len(arr)  print("Maximum water that can be accumulated is ",        findWater(arr, n))  # This code is contributed# by Anant Agarwal.
// C# Code For Trapping Rain Waterusing System;  class GFG {      static int findWater(int[] arr, int n)    {        // initialize output        int result = 0;          // maximum element on left and right        int left_max = 0, right_max = 0;          // indices to traverse the array        int lo = 0, hi = n - 1;          while (lo <= hi) {            if (arr[lo] < arr[hi]) {                if (arr[lo] > left_max)                      // update max in left                    left_max = arr[lo];                else                      // water on curr element =                    // max - curr                    result += left_max - arr[lo];                lo++;            }            else {                if (arr[hi] > right_max)                      // update right maximum                    right_max = arr[hi];                  else                    result += right_max - arr[hi];                hi--;            }        }          return result;    }      // Driver program    public static void Main()    {        int[] arr = { 0, 1, 0, 2, 1, 0, 1,                      3, 2, 1, 2, 1 };        int result = Trap.findWater(arr, arr.length);        System.out.print(" Total trapping water: " + result);    }}  // This code is contributed by vt_m.
<?php// PHP program to find maximum amount// of water that can be trapped within // given set of bars.  // Method to find maximum amount// of water that can be trapped within // given set of bars.function findWater($arr, $n){          // initialize output    $result = 0;          // maximum element on     // left and right    $left_max = 0;     $right_max = 0;          // indices to traverse     // the array    $lo = 0; $hi = $n - 1;          while($lo <= $hi)     {        if($arr[$lo] < $arr[$hi])        {            if($arr[$lo] > $left_max)                              // update max in left                $left_max = $arr[$lo];                          else                              // water on curr                 // element = max - curr                $result += $left_max - $arr[$lo];                $lo++;        }        else        {            if($arr[$hi] > $right_max)                              // update right maximum                $right_max = $arr[$hi];            else                $result += $right_max - $arr[$hi];                $hi--;        }    }          return $result;}      // Driver Code    $arr = array(0, 1, 0, 2, 1, 0,                  1, 3, 2, 1, 2, 1);    $n = count($arr);    echo "Maximum water that can be accumulated is ", findWater($arr, $n);   // This code is contributed by anuj_67.?>
<script>// JAVASCRIPT Code For Trapping Rain Water  function findWater(arr,n){        // initialize output        let result = 0;           // maximum element on left and right        let left_max = 0, right_max = 0;           // indices to traverse the array        let lo = 0, hi = n - 1;           while (lo <= hi) {            if (arr[lo] < arr[hi]) {                if (arr[lo] > left_max)                       // update max in left                    left_max = arr[lo];                else                       // water on curr element =                    // max - curr                    result += left_max - arr[lo];                lo++;            }            else {                if (arr[hi] > right_max)                       // update right maximum                    right_max = arr[hi];                   else                    result += right_max - arr[hi];                hi--;            }        }           return result;}   /* Driver program to test above function */let arr=[0, 1, 0, 2, 1, 0, 1,                      3, 2, 1, 2, 1];let n = arr.length;document.write("Maximum water that "                           + "can be accumulated is "                           + findWater(arr, n));      // This code is contributed by ab2127</script>
// Implementation in C of the above approach  // Importing the required header files#include <stdio.h>  // 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 storedint findWater(int arr[], int n){          // initialize output    int result = 0;      //maximum element on left and right     int left_max = 0, right_max = 0;      // indices to traverse the array    int lo = 0, hi = n-1;      while (lo <= hi){        if (arr[lo] < arr[hi]){            if(arr[lo] > left_max){                                  // update left max                left_max = arr[lo];}            else                // water on curr element  = max - curr                {result += left_max - arr[lo];}            lo++;        }        else{            if(arr[hi] > right_max){                // update right max                right_max = arr[hi];            }            else                // water on curr element  = max - curr                {result += right_max - arr[hi];}            hi--;        }    }    return result;}    // Driver codeint main(){    int arr[] = {0,1,0,2,1,0,1,3,2,1,2,1};    int n = sizeof(arr)/sizeof(arr[0]);    printf("Maximum water that can be accumulated is %d", findWater(arr, n));    return 0;}
Maximum water that can be accumulated is 6
Complexity Analysis: Time Complexity: O(n). Only one traversal of the array is needed.Auxiliary Space: O(1). As no extra space is required.
Time Complexity: O(n). Only one traversal of the array is needed.
Auxiliary Space: O(1). As no extra space is required.
Thanks to Gaurav Ahirwar and Aditi Sharma for the above solution.  
Method 3: Here another efficient solution has been shown.
Approach: The concept here is that if there is a larger wall to the right, then the water can be retained with a height equal to the smaller wall on the left. If there are no larger walls to the right, then start from the left. There must be a larger wall to the left now. Let’s take an example of the heights are {....,3, 2, 1, 4,....}, So here 3 and 4 are boundaries the heights 2 and 1 are submerged and cannot act as boundaries. So at any point or index knowing the previous boundary is sufficient if there is a higher or equal length boundary in the remaining part of the array. If not, then traverse the array backward and now must be a larger wall to the left.  
Algorithm: Loop from index 0 to the end of the given array.If a wall greater than or equal to the previous wall is encountered, then make note of the index of that wall in a var called prev_index.Keep adding the previous wall’s height minus the current (ith) wall to the variable water.Have a temporary variable that stores the same value as water.If no wall greater than or equal to the previous wall is found, then quit.If prev_index < size of the input array, then subtract the temp variable from water, and loop from the end of the input array to prev_index. Find a wall greater than or equal to the previous wall (in this case, the last wall from backward).
Loop from index 0 to the end of the given array.
If a wall greater than or equal to the previous wall is encountered, then make note of the index of that wall in a var called prev_index.
Keep adding the previous wall’s height minus the current (ith) wall to the variable water.
Have a temporary variable that stores the same value as water.
If no wall greater than or equal to the previous wall is found, then quit.
If prev_index < size of the input array, then subtract the temp variable from water, and loop from the end of the input array to prev_index. Find a wall greater than or equal to the previous wall (in this case, the last wall from backward).
Implementation:
C++
Java
Python3
C#
Javascript
C
// C++ implementation of the approach#include<iostream>using namespace std;  // Function to return the maximum// water that can be storedint 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 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 Codeint main(){    int arr[] = { 0, 1, 0, 2, 1, 0,                   1, 3, 2, 1, 2, 1 };     int n = sizeof(arr) / sizeof(arr[0]);      cout << maxWater(arr, n);    return 0;}  // This code is contributed by Debidutta Rath
// Java implementation of the approachclass 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 implementation of the approach  # Function to return the maximum# water that can be storeddef 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 codearr = [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# implementation of the approachusing 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[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 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
<script>  // JavaScript implementation of the approach      // Function to return the maximum    // water that can be stored    function maxWater(arr,n)    {        let size = n - 1;           // Let the first element be stored as        // previous, we shall loop from index 1        let prev = arr[0];           // To store previous wall's index        let prev_index = 0;        let water = 0;           // To store the water until a larger wall        // is found, if there are no larger walls        // then delete temp value from water        let temp = 0;        for (let 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 (let 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    let arr=[ 0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1];    let n = arr.length;    document.write(maxWater(arr, n));    // This code is contributed by patel2127  </script>
// Implementation in C of the above approach  // Importing the required header files#include <stdio.h> // 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 storedint 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 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[0]);    printf("%d", maxWater(arr, n));    return 0;}
6
Complexity Analysis: Time Complexity: O(n). As only one traversal of the array is needed.Auxiliary Space: O(1). As no extra space is required.
Time Complexity: O(n). As only one traversal of the array is needed.
Auxiliary Space: O(1). As no extra space is required.
Method 4 (Using Stack):
We can use a Stack to track the bars that are bounded by the longer left and right bars. This can be done using only one iteration using stacks.
Approach:
1. Loop through the indices of the bar array.
2. For each bar, we can do the following:
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 in distance * min_height.
The water trapped, including the popped bar, is (distance * min_height) – height[pop_height].
Add that to the fans.
3. Final answer will the ans.
C++
Java
Python3
C#
Javascript
// C++ implementation of the approach#include <bits/stdc++.h> using namespace std;  // Function to return the maximum// water that can be storedint 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 codeint main() {          int arr[] = { 0, 1, 0, 2, 1, 0,                  1, 3, 2, 1, 2, 1 };    int n = sizeof(arr) / sizeof(arr[0]);          cout << maxWater(arr, n);      return 0;}  // The code is contributed by Soumitri Chattopadhyay
import java.util.*;import java.io.*;  // Java implementation of the approachclass GFG {      // Function to return the maximum    // water that can be stored    public static int maxWater(int[] height)    {        // Stores the indices of the bars        Stack<Integer> 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));    }}
# Python implementation of the approach  # Function to return the maximum# water that can be storeddef 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 codearr=[ 0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1]print(maxWater(arr))  # This code is contributed by rag2127
using System;using System.Collections;using System.Collections.Generic;  // C# implementation of the approachclass 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.
<script>  // Python implementation of the approach  // Function to return the maximum// water that can be storedfunction maxWater(height){          // Stores the indices of the bars    let stack = []          // size of the array    let n = height.length          // Stores the final result    let ans = 0          // Loop through the each bar    for(let i=0;i<n;i++){                  // Remove bars from the stack        // until the condition holds        while(stack.length != 0 && (height[stack[stack.length-1]] < height[i]) ){                          // store the height of the top            // and pop it.            let pop_height = height[stack.pop()]                          // If the stack does not have any            // bars or the popped bar            // has no left boundary            if(stack.length == 0)                break                          // Get the distance between the            // left and right boundary of            // popped bar            let distance = i - stack[stack.length - 1] - 1                          // Calculate the min. height            let min_height =Math.min(height[stack[stack.length - 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.push(i)    }          return ans}  // Driver codelet arr = [ 0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1]document.write(maxWater(arr))  // This code is contributed by shinjanpatra  </script>
6
Time Complexity: O(n)Auxiliary Space: O(n) 
Method 5 (Two Pointer Approach)
Approach: 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
Algorithm :Take two pointers l and r. Initialize l to the starting index 0 and r to the last index n-1Since l is the first element, left_max would be 0, and right max for r would be 0While l <= r, iterate the array. We have two possible conditionsCondition1 : left_max <= right maxConsider Element at index lSince 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 hereSo, min(left_max,right_max) would always equal to left_max in this caseIncrement lCondition2 : left_max >  right maxConsider Element at index rSince we have traversed all elements to the right of r, right_max is knownFor the left max of l, We can say that the left max would  always be >= current l_max hereSo, min(left_max,right_max) would always equal to right_max in this caseDecrement r
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 maxConsider Element at index lSince 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 hereSo, min(left_max,right_max) would always equal to left_max in this caseIncrement l
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 maxConsider Element at index rSince we have traversed all elements to the right of r, right_max is knownFor the left max of l, We can say that the left max would  always be >= current l_max hereSo, min(left_max,right_max) would always equal to right_max in this caseDecrement r
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
Implementation:
C++
Java
Python3
C#
Javascript
C
// C++ implementation of the approach#include <iostream>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 codeint main() {    int arr[] = {0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1};    int n = sizeof(arr)/sizeof(arr[0]);    cout << maxWater(arr, n) << endl;    return 0;}  // This code is contributed by avanitrachhadiya2155
// Java implementation of the approachimport 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 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 codearr = [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# implementation of the approachusing 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.
<script>  // Javascript implementation of the approachfunction maxWater(arr, n){          // indices to traverse the array    let left = 0;    let right = n - 1;          // To store Left max and right max    // for two pointers left and right    let l_max = 0;    let r_max = 0;          // To store the total amount    // of rain water trapped    let 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  let arr = [ 0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1 ];let n = arr.length;  document.write(maxWater(arr, n));  // This code is contributed by suresh07  </script>
// Implementation in C of the above approach  // Importing the required header files#include <stdio.h> // 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[0]);    printf("%d", maxWater(arr, n));    return 0;}
6
Time Complexity: O(n)Auxiliary Space: O(1) 
Method 6 (horizontal scan method)
Approach If max_height is the height of the tallest block, then it will be the maximum possible height for any trapped rainwater. And if we traverse each row from left to right for each row from bottom to max_height, we can count the number of blocks that will contain water.
AlgorithmFind the total number of blocks, i.e., sum of the heights array, num_blocksfind the maximum height, max_heightstore total water in a variable, total = 0keep two pointers, left = 0 and right = n -1, we will use them laterfor each row i from 0 to max_height, do the followingScan heights array from left to right, if height > i (current row), this will be the boundary of one of the sections of trapped water, let us store these indexes.Let the boundary indexes be boundary = [i1, i2, i3 ...]The water stored in current row between i1 and i2 = i2 – i1 – 1, between i2 and i3 = i3 – i2 – 1 and so on.Total water stored in current row = (i2 – i1 – 1) + (i3 – i2 – 1) + ... (in – in-1 -1) = in – i1 – (k – 1), where k in number of blocks in this rowif we find i1 and in i.e., first and last boundary index of each row, we don’t need to scan the whole array. We will not find k, since it is a number of blocks in current row, it will accumulate and it will add up to total number of blocks, which we have found already, and the 1 will accumulate for each row, i.e., it will become max_heightfind i1 by traversing from left towards right till you find h where h > i (current row), similarly, find in by traversing from right towards left.Set left = i1 and right = in  and add in – i1 to totalsubtract num_blocks – max_height from total, which was accumulatedtotal will be the quantity of trapped water
Find the total number of blocks, i.e., 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, we will use them later
for each row i from 0 to max_height, do the followingScan heights array from left to right, if height > i (current row), this will be the boundary of one of the sections of trapped water, let us store these indexes.Let the boundary indexes be boundary = [i1, i2, i3 ...]The water stored in current row between i1 and i2 = i2 – i1 – 1, between i2 and i3 = i3 – i2 – 1 and so on.Total water stored in current row = (i2 – i1 – 1) + (i3 – i2 – 1) + ... (in – in-1 -1) = in – i1 – (k – 1), where k in number of blocks in this rowif we find i1 and in i.e., first and last boundary index of each row, we don’t need to scan the whole array. We will not find k, since it is a number of blocks in current row, it will accumulate and it will add up to total number of blocks, which we have found already, and the 1 will accumulate for each row, i.e., it will become max_heightfind i1 by traversing from left towards right till you find h where h > i (current row), similarly, find in by traversing from right towards left.Set left = i1 and right = in  and add in – i1 to total
Scan heights array from left to right, if height > i (current row), this will be the boundary of one of the sections of trapped water, let us store these indexes.
Let the boundary indexes be boundary = [i1, i2, i3 ...]
The water stored in current row between i1 and i2 = i2 – i1 – 1, between i2 and i3 = i3 – i2 – 1 and so on.
Total water stored in current row = (i2 – i1 – 1) + (i3 – i2 – 1) + ... (in – in-1 -1) = in – i1 – (k – 1), where k in number of blocks in this row
if we find i1 and in i.e., first and last boundary index of each row, we don’t need to scan the whole array. We will not find k, since it is a number of blocks in current row, it will accumulate and it will add up to total number of blocks, which we have found already, and the 1 will accumulate for each row, i.e., it will become max_height
find i1 by traversing from left towards right till you find h where h > i (current row), similarly, find in by traversing from right towards left.
Set left = i1 and right = in  and add in – i1 to total
subtract num_blocks – max_height from total, which was accumulated
total will be the quantity of trapped water
Implementation
C++
Java
Python
Javascript
// C++ program to implement the approach#include <bits/stdc++.h>using namespace std;  int trappedWater(vector<int>&heights){    int num_blocks = 0;    int n = 0;    int max_height = INT_MIN;          // Find total blocks, max height and length of array    for(auto height : heights){        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 = 0; i < max_height; i++)    {                // Find leftmost point greater than current row (i)        while(heights[left] <= i)            left += 1;                // Find rightmost point greater than current row (i)        while(heights[right] <= i)            right -= 1;                // water in this row = right - left - (k - 1), where k - 1 accumulates        total += right - left;    }              // k - 1 accumulates to num_blocks - max_height,  // subtract it to get actual answer    total -= (num_blocks - max_height);    return total;}  // Driver codeint main(){    vector<int> heights = {0,1,0,2,1,0,1,3,2,1,2,1};  cout << trappedWater(heights) << endl;  return 0;  }  // This code is contributed by shinjanpatra
//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[]){                  int n = arr.length; //to store the number of blocks        int num_blocks=0; //to store the sum of all the heights        int max_height = Integer.MIN_VALUE; //to store the maximum height in the array                  //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=0;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 - (k - 1), where k - 1 accumulates            total+=right-left;        }                  //k - 1 accumulates to num_blocks - max_height.        // Hence, subtract it to get actual answer        total-=num_blocks-max_height;        return total;    }          //Driver Code    public static void main (String[] args) {        int arr[] = {0,1,0,2,1,0,1,3,2,1,2,1}; //sample array to test        System.out.println(trappedWater(arr)); //function call    }}  //this code is contributed by shruti456rawal
def trappedWater(heights):    num_blocks = 0    n = 0    max_height = float('-inf')          # Find total blocks, max height and length of array          for height in heights:        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(max_height):        # Find leftmost point greater than current row (i)        while heights[left] <= i:            left += 1        # Find rightmost point greater than current row (i)        while heights[right] <= i:            right -= 1        # water in this row = right - left - (k - 1), where k - 1 accumulates        total += right - left              # k - 1 accumulates to num_blocks - max_height, subtract it to get actual answer              total -= (num_blocks - max_height)    return total  if __name__ == "__main__":    heights = [0,1,0,2,1,0,1,3,2,1,2,1]    print(trappedWater(heights))
<script>  function trappedWater(heights){    let num_blocks = 0    let n = 0    let max_height =Number.MIN_VALUE          // Find total blocks, max height and length of array          for(let height of heights){        num_blocks += height        n += 1        max_height = Math.max(max_height, height)    }              // Total water, left pointer and right pointer initialized to 0 and n - 1              let total = 0    let left = 0    let right = n - 1          for(let i=0;i<max_height;i++){        // Find leftmost point greater than current row (i)        while(heights[left] <= i)            left += 1        // Find rightmost point greater than current row (i)        while(heights[right] <= i)            right -= 1        // water in this row = right - left - (k - 1), where k - 1 accumulates        total += right - left    }              // k - 1 accumulates to num_blocks - max_height, subtract it to get actual answer              total -= (num_blocks - max_height)    return total}  // driver codelet heights = [0,1,0,2,1,0,1,3,2,1,2,1]document.write(trappedWater(heights))  // This code is contributed by shinjanpatra  </script>
6
Time Complexity: O(max_height * k) where k is total change in left and right pointers per row, k < nSpace Complexity: O(1)
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above. 
jit_t
vt_m
sakhidamaulik
Ashwin Subu
ankthon
mohit kumar 29
andrew1234
AmiyaRanjanRout
Ganeshchowdharysadanala
chatterjee0soumitri
parascoding
shivanisinghss2110
nikhil ch
divyesh072019
divyeshrabadiya07
rutvik_56
pratham76
avanitrachhadiya2155
rag2127
azmuth
kumarishaan01
suresh07
decode2207
unknown2108
SubhrodipMohanta
ab2127
patel2127
singhashwani2002
theabbie
simranarora5sos
arorakashish0911
surinderdawra388
amnindersingh1414
shinjanpatra
shruti456rawal
parthshar48
Accolite
Adobe
Amazon
D-E-Shaw
MakeMyTrip
Microsoft
Payu
Arrays
Accolite
Amazon
Microsoft
D-E-Shaw
MakeMyTrip
Payu
Adobe
Arrays
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.