Skip to content

Instantly share code, notes, and snippets.

@mrap
Last active August 29, 2015 14:15
Show Gist options
  • Save mrap/b64f39ee81706e02c4bc to your computer and use it in GitHub Desktop.
Save mrap/b64f39ee81706e02c4bc to your computer and use it in GitHub Desktop.
Calculating max fluid volume in O(n) time
#include <iostream>
#include <algorithm>
typedef int pillar_t;
pillar_t* read_pillars(int);
int get_volume(pillar_t *, int);
int main() {
int count;
std::cin >> count;
pillar_t * pillars = read_pillars(count);
std::cout << get_volume(pillars, count);
delete []pillars;
return 0;
}
pillar_t* read_pillars(int count) {
pillar_t * pillars = new pillar_t[count]();
for (int i = 0; i < count; ++i) {
std::cin >> pillars[i];
}
return pillars;
}
int get_volume(pillar_t * pillars, int count) {
int volume = 0;
int valley_height = 0;
int left = 0;
int right = 0;
int tallest_height = 0;
int tallest_index = -1;
while (left < count - 1) {
// 1. Move left until peak
while (pillars[left] <= pillars[left+1]) {
if (++left >= count -1) {
break;
}
}
// 2. Find right edge: anything greater than or equal to left.
// Else If no right edge, revert to the tallest peak along the way
right = left;
tallest_height = 0;
tallest_index = -1;
while (++right < count) {
if (pillars[right] >= pillars[left]) {
break;
}
// Found a new tallest peak
if (pillars[right] > tallest_height && pillars[right] > pillars[right-1]) {
tallest_height = pillars[right];
tallest_index = right;
}
}
// If right ran off the edge
if (right == count) {
if (tallest_index == -1) {
// No other volume to add, no more peaks!
break;
}
right = tallest_index;
}
valley_height = std::min(pillars[left], pillars[right]);
// 3. Move left to meet right while adding volume along the way
while (++left < right) {
volume += valley_height - pillars[left];
}
}
return volume;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment