Below is the implementation of the rain water collector:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119/** * Calculate how much rainwater can be trapped between buildings. * Dynamic Programming approach. * * @param {number[]} heights - Array of building heights * @return {number} - Total amount of trapped water */function trapDP(heights) { const n = heights.length; if (n <= 2) return 0; // Precompute maximum heights to the left and right const leftMax = new Array(n); const rightMax = new Array(n); // Initialize leftMax and rightMax leftMax[0] = heights[0]; rightMax[n - 1] = heights[n - 1]; // Fill leftMax array for (let i = 1; i < n; i++) { leftMax[i] = Math.max(leftMax[i - 1], heights[i]); } // Fill rightMax array for (let i = n - 2; i >= 0; i--) { rightMax[i] = Math.max(rightMax[i + 1], heights[i]); } // Calculate trapped water let totalWater = 0; for (let i = 0; i < n; i++) { totalWater += Math.min(leftMax[i], rightMax[i]) - heights[i]; } return totalWater;} /** * Calculate how much rainwater can be trapped between buildings. * Two Pointers approach. * * @param {number[]} heights - Array of building heights * @return {number} - Total amount of trapped water */function trapTwoPointers(heights) { const n = heights.length; if (n <= 2) return 0; let left = 0; let right = n - 1; let leftMax = heights[left]; let rightMax = heights[right]; let totalWater = 0; while (left < right) { if (leftMax < rightMax) { left++; leftMax = Math.max(leftMax, heights[left]); totalWater += leftMax - heights[left]; } else { right--; rightMax = Math.max(rightMax, heights[right]); totalWater += rightMax - heights[right]; } } return totalWater;} /** * Calculate how much rainwater can be trapped between buildings. * Stack-Based approach. * * @param {number[]} heights - Array of building heights * @return {number} - Total amount of trapped water */function trapStack(heights) { const n = heights.length; if (n <= 2) return 0; const stack = []; let totalWater = 0; for (let i = 0; i < n; i++) { // While the current building is taller than the building at the top of the stack while (stack.length > 0 && heights[i] > heights[stack[stack.length - 1]]) { const top = stack.pop(); // If the stack is empty, there's no left boundary if (stack.length === 0) break; // Calculate the width of the water trap const width = i - stack[stack.length - 1] - 1; // Calculate the height of the water trap const height = Math.min(heights[i], heights[stack[stack.length - 1]]) - heights[top]; // Add the volume of water trapped totalWater += width * height; } // Push the current index onto the stack stack.push(i); } return totalWater;} // Test casesconst heights1 = [0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1];console.log(trapDP(heights1)); // 6console.log(trapTwoPointers(heights1)); // 6console.log(trapStack(heights1)); // 6 const heights2 = [4, 2, 0, 3, 2, 5];console.log(trapDP(heights2)); // 9console.log(trapTwoPointers(heights2)); // 9console.log(trapStack(heights2)); // 9
Let's break down the implementation:
Implement the rain water collector solution in different programming languages.
Below is the implementation of the rain water collector in different programming languages. Select a language tab to view the corresponding code.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119/** * Calculate how much rainwater can be trapped between buildings. * Dynamic Programming approach. * * @param {number[]} heights - Array of building heights * @return {number} - Total amount of trapped water */function trapDP(heights) { const n = heights.length; if (n <= 2) return 0; // Precompute maximum heights to the left and right const leftMax = new Array(n); const rightMax = new Array(n); // Initialize leftMax and rightMax leftMax[0] = heights[0]; rightMax[n - 1] = heights[n - 1]; // Fill leftMax array for (let i = 1; i < n; i++) { leftMax[i] = Math.max(leftMax[i - 1], heights[i]); } // Fill rightMax array for (let i = n - 2; i >= 0; i--) { rightMax[i] = Math.max(rightMax[i + 1], heights[i]); } // Calculate trapped water let totalWater = 0; for (let i = 0; i < n; i++) { totalWater += Math.min(leftMax[i], rightMax[i]) - heights[i]; } return totalWater;} /** * Calculate how much rainwater can be trapped between buildings. * Two Pointers approach. * * @param {number[]} heights - Array of building heights * @return {number} - Total amount of trapped water */function trapTwoPointers(heights) { const n = heights.length; if (n <= 2) return 0; let left = 0; let right = n - 1; let leftMax = heights[left]; let rightMax = heights[right]; let totalWater = 0; while (left < right) { if (leftMax < rightMax) { left++; leftMax = Math.max(leftMax, heights[left]); totalWater += leftMax - heights[left]; } else { right--; rightMax = Math.max(rightMax, heights[right]); totalWater += rightMax - heights[right]; } } return totalWater;} /** * Calculate how much rainwater can be trapped between buildings. * Stack-Based approach. * * @param {number[]} heights - Array of building heights * @return {number} - Total amount of trapped water */function trapStack(heights) { const n = heights.length; if (n <= 2) return 0; const stack = []; let totalWater = 0; for (let i = 0; i < n; i++) { // While the current building is taller than the building at the top of the stack while (stack.length > 0 && heights[i] > heights[stack[stack.length - 1]]) { const top = stack.pop(); // If the stack is empty, there's no left boundary if (stack.length === 0) break; // Calculate the width of the water trap const width = i - stack[stack.length - 1] - 1; // Calculate the height of the water trap const height = Math.min(heights[i], heights[stack[stack.length - 1]]) - heights[top]; // Add the volume of water trapped totalWater += width * height; } // Push the current index onto the stack stack.push(i); } return totalWater;} // Test casesconst heights1 = [0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1];console.log(trapDP(heights1)); // 6console.log(trapTwoPointers(heights1)); // 6console.log(trapStack(heights1)); // 6 const heights2 = [4, 2, 0, 3, 2, 5];console.log(trapDP(heights2)); // 9console.log(trapTwoPointers(heights2)); // 9console.log(trapStack(heights2)); // 9
First, understand that we need to calculate how much rainwater can be trapped between buildings of varying heights.
Recognize that for each position, the amount of water trapped depends on the minimum of the maximum heights to its left and right.
Precompute the maximum heights to the left and right of each position, then calculate the trapped water.
Use two pointers to scan the array from both ends, keeping track of the maximum heights seen so far.
Use a stack to keep track of indices of buildings that can potentially trap water.
Modify the code to implement an alternative approach and test it with the same examples.
Implement a function that solves the rain water collector problem using a different approach than shown above.
Handle the case where there are no buildings or only one building (no water can be trapped).
Handle the case where building heights are in decreasing order (no water can be trapped).
Handle the case where building heights are in increasing order (no water can be trapped).
Below is the implementation of the rain water collector:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119/** * Calculate how much rainwater can be trapped between buildings. * Dynamic Programming approach. * * @param {number[]} heights - Array of building heights * @return {number} - Total amount of trapped water */function trapDP(heights) { const n = heights.length; if (n <= 2) return 0; // Precompute maximum heights to the left and right const leftMax = new Array(n); const rightMax = new Array(n); // Initialize leftMax and rightMax leftMax[0] = heights[0]; rightMax[n - 1] = heights[n - 1]; // Fill leftMax array for (let i = 1; i < n; i++) { leftMax[i] = Math.max(leftMax[i - 1], heights[i]); } // Fill rightMax array for (let i = n - 2; i >= 0; i--) { rightMax[i] = Math.max(rightMax[i + 1], heights[i]); } // Calculate trapped water let totalWater = 0; for (let i = 0; i < n; i++) { totalWater += Math.min(leftMax[i], rightMax[i]) - heights[i]; } return totalWater;} /** * Calculate how much rainwater can be trapped between buildings. * Two Pointers approach. * * @param {number[]} heights - Array of building heights * @return {number} - Total amount of trapped water */function trapTwoPointers(heights) { const n = heights.length; if (n <= 2) return 0; let left = 0; let right = n - 1; let leftMax = heights[left]; let rightMax = heights[right]; let totalWater = 0; while (left < right) { if (leftMax < rightMax) { left++; leftMax = Math.max(leftMax, heights[left]); totalWater += leftMax - heights[left]; } else { right--; rightMax = Math.max(rightMax, heights[right]); totalWater += rightMax - heights[right]; } } return totalWater;} /** * Calculate how much rainwater can be trapped between buildings. * Stack-Based approach. * * @param {number[]} heights - Array of building heights * @return {number} - Total amount of trapped water */function trapStack(heights) { const n = heights.length; if (n <= 2) return 0; const stack = []; let totalWater = 0; for (let i = 0; i < n; i++) { // While the current building is taller than the building at the top of the stack while (stack.length > 0 && heights[i] > heights[stack[stack.length - 1]]) { const top = stack.pop(); // If the stack is empty, there's no left boundary if (stack.length === 0) break; // Calculate the width of the water trap const width = i - stack[stack.length - 1] - 1; // Calculate the height of the water trap const height = Math.min(heights[i], heights[stack[stack.length - 1]]) - heights[top]; // Add the volume of water trapped totalWater += width * height; } // Push the current index onto the stack stack.push(i); } return totalWater;} // Test casesconst heights1 = [0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1];console.log(trapDP(heights1)); // 6console.log(trapTwoPointers(heights1)); // 6console.log(trapStack(heights1)); // 6 const heights2 = [4, 2, 0, 3, 2, 5];console.log(trapDP(heights2)); // 9console.log(trapTwoPointers(heights2)); // 9console.log(trapStack(heights2)); // 9
Let's break down the implementation:
Implement the rain water collector solution in different programming languages.
Below is the implementation of the rain water collector in different programming languages. Select a language tab to view the corresponding code.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119/** * Calculate how much rainwater can be trapped between buildings. * Dynamic Programming approach. * * @param {number[]} heights - Array of building heights * @return {number} - Total amount of trapped water */function trapDP(heights) { const n = heights.length; if (n <= 2) return 0; // Precompute maximum heights to the left and right const leftMax = new Array(n); const rightMax = new Array(n); // Initialize leftMax and rightMax leftMax[0] = heights[0]; rightMax[n - 1] = heights[n - 1]; // Fill leftMax array for (let i = 1; i < n; i++) { leftMax[i] = Math.max(leftMax[i - 1], heights[i]); } // Fill rightMax array for (let i = n - 2; i >= 0; i--) { rightMax[i] = Math.max(rightMax[i + 1], heights[i]); } // Calculate trapped water let totalWater = 0; for (let i = 0; i < n; i++) { totalWater += Math.min(leftMax[i], rightMax[i]) - heights[i]; } return totalWater;} /** * Calculate how much rainwater can be trapped between buildings. * Two Pointers approach. * * @param {number[]} heights - Array of building heights * @return {number} - Total amount of trapped water */function trapTwoPointers(heights) { const n = heights.length; if (n <= 2) return 0; let left = 0; let right = n - 1; let leftMax = heights[left]; let rightMax = heights[right]; let totalWater = 0; while (left < right) { if (leftMax < rightMax) { left++; leftMax = Math.max(leftMax, heights[left]); totalWater += leftMax - heights[left]; } else { right--; rightMax = Math.max(rightMax, heights[right]); totalWater += rightMax - heights[right]; } } return totalWater;} /** * Calculate how much rainwater can be trapped between buildings. * Stack-Based approach. * * @param {number[]} heights - Array of building heights * @return {number} - Total amount of trapped water */function trapStack(heights) { const n = heights.length; if (n <= 2) return 0; const stack = []; let totalWater = 0; for (let i = 0; i < n; i++) { // While the current building is taller than the building at the top of the stack while (stack.length > 0 && heights[i] > heights[stack[stack.length - 1]]) { const top = stack.pop(); // If the stack is empty, there's no left boundary if (stack.length === 0) break; // Calculate the width of the water trap const width = i - stack[stack.length - 1] - 1; // Calculate the height of the water trap const height = Math.min(heights[i], heights[stack[stack.length - 1]]) - heights[top]; // Add the volume of water trapped totalWater += width * height; } // Push the current index onto the stack stack.push(i); } return totalWater;} // Test casesconst heights1 = [0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1];console.log(trapDP(heights1)); // 6console.log(trapTwoPointers(heights1)); // 6console.log(trapStack(heights1)); // 6 const heights2 = [4, 2, 0, 3, 2, 5];console.log(trapDP(heights2)); // 9console.log(trapTwoPointers(heights2)); // 9console.log(trapStack(heights2)); // 9
First, understand that we need to calculate how much rainwater can be trapped between buildings of varying heights.
Recognize that for each position, the amount of water trapped depends on the minimum of the maximum heights to its left and right.
Precompute the maximum heights to the left and right of each position, then calculate the trapped water.
Use two pointers to scan the array from both ends, keeping track of the maximum heights seen so far.
Use a stack to keep track of indices of buildings that can potentially trap water.
Modify the code to implement an alternative approach and test it with the same examples.
Implement a function that solves the rain water collector problem using a different approach than shown above.
Handle the case where there are no buildings or only one building (no water can be trapped).
Handle the case where building heights are in decreasing order (no water can be trapped).
Handle the case where building heights are in increasing order (no water can be trapped).