Last active
August 29, 2015 14:15
-
-
Save mrap/b64f39ee81706e02c4bc to your computer and use it in GitHub Desktop.
Calculating max fluid volume in O(n) time
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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