Given n non-negative integers a1, a2, ..., an , where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of the line i is at (i, ai) and (i, 0). Find two lines, which, together with the x-axis forms a container, such that the container contains the most water.
Notice that you may not slant the container.
Input: height = [1,8,6,2,5,4,8,3,7]
Output: 49
Explanation: The above vertical lines are represented by array [1,8,6,2,5,4,8,3,7]. In this case, the max area of water (blue section) the container can contain is 49.
You are given an array of N non-negative integers. Imagine the array as a set of walls in which each integer represents the height of a wall. Its index represents its location relative to the other walls. Any two walls can be used to contain a specific amount of water. The amount of water two walls can hold is equal to the area.
When finding the area at two walls, you ignore all the walls in between them.
You return a single number. This number represents an area. Specifically, it represents the maximum possible area that can be created using two walls in the input array.
The first approach idea that may come to mind is brute fore approach wherein you check the area that will be created with every single possible combination of walls.
This approach will:
Things to consider:
Although approach one works, there is a way to solve the problem in O(N) time. Approach two will utilize a single while loop as opposed to a for loop with an additional for loop nested inside. Consider that every single possible combination of walls does not need to be checked. An algorithm can be implemented that uses the information at each iteration to decide how to proceed through the single for loop in a way that still guarantees the max area will be found at some point. This is done using pointers. One pointer will be initialized to the beginning of the array and other will be initialized to the end.
Similarities to approach one:
Differences to approach one:
Things to consider:
Below is raw code, the same code with comments, and again with an example.
// raw code
function water(array) {
let currentArea = 0
let maxArea = 0
let left = 0
let right = array.length - 1
while (left < right) {
currentArea = areaCalculator(left , right, array)
maxArea = Math.max(maxArea, currentArea)
if (array[left] > array[right]) {
right--
} else {
left++
}
}
return maxArea
}
function areaCalculator(i, j, array) {
let height = Math.min(array[i], array[j])
let width = j - i
let area = width * height
return area
}
// with notes
function water1(array) {
// initialize variables
let currentArea = 0 // will be recalculated at every iteration
let maxArea = 0 // will be replaced by current area whenever current area is greater, will be returned at the end
let left = 0 // used to reference an index in the array, initialized to the beginning index
let right = array.length - 1 // used to reference an index in the array, initialized to the end index
// while loop to find maxArea
while (left < right) { // the loop continues until every index is checked once
currentArea = areaCalculator(left , right, array) // use the information at the two current indices to find the current area
maxArea = Math.max(maxArea, currentArea) // overwrite the maxArea value if appropriate
if (array[left] > array[right]) { // determine which pointer to move toward the center
right--
} else {
left++
}
}
return maxArea
}
function areaCalculator1(i, j, array) {
let height = Math.min(array[i], array[j]) // find the lower of the two heights based on the values at their indices
let width = j - i // calculate width based on the two indices
let area = width * height
return area
}
// with example
function water2(array) {
let currentArea = 0
let maxArea = 0
let left = 0
let right = array.length - 1 // 3
// each '|' separates the values for each iteration
while (left < right) { // 0 < 3 | 1 < 3 | 2 < 3 | 3 < 3 is false, end loop
currentArea = areaCalculator(left , right, array) // 9 | 10 | 7
maxArea = Math.max(maxArea, currentArea) // 9 | 10 | 10
if (array[left] > array[right]) { // false | false | false
right--
} else {
left++
}
// left = 1, right = 3 | left = 2, right = 3 | left = 3, right = 3
}
return maxArea // 10
}
function areaCalculator2(i, j, array) {
let height = Math.min(array[i], array[j]) // 3 | 5 | 7
let width = j - i // 3 | 2 | 1
let area = width * height // 9 | 10 | 7
return area // 9 | 10 | 7
}