Info
#include <functional>
#include <iostream>
#include <print>
#include <ranges>
#include <stack>
#include <vector>
namespace UsingStack {
template<typename Compare>
std::vector<int> computePreviousSmallerElement(std::ranges::constant_range auto&& arr, Compare&& cmp) {
std::stack<int> stack;
std::vector<int> prevElem;
for (auto const& [idx, elem]: arr | std::views::enumerate) {
while (!stack.empty() && cmp(elem, arr[stack.top()])) {
stack.pop();
}
auto prevElemIdx = stack.empty() ? -1 : stack.top();
prevElem.push_back(prevElemIdx);
stack.push(idx);
}
return prevElem;
}
}
namespace UsingJumpPointers {
template<typename Compare>
std::vector<int> computePreviousSmallerElement(std::ranges::constant_range auto&& arr, Compare&& cmp) {
std::vector<int> prevElem;
for (auto const& [idx, elem]: arr | std::views::enumerate) {
auto prevElemIdx = idx - 1;
while (prevElemIdx != -1 && cmp(elem, arr[prevElemIdx])) {
prevElemIdx = prevElem[prevElemIdx];
}
prevElem.push_back(prevElemIdx);
}
return prevElem;
}
}
int largestRectangleInHistogram(std::vector<int> const& arr) {
using namespace UsingJumpPointers;
auto leftSmallerElements = computePreviousSmallerElement(arr, std::less_equal<int>());
auto rightSmallerElements = computePreviousSmallerElement(arr | std::views::reverse, std::less_equal<int>())
| std::views::reverse
| std::views::transform([size = static_cast<int>(arr.size())](auto const& reversedIdx) {
return size - 1 - reversedIdx;
})
| std::ranges::to<std::vector>();
int maxArea = 0;
for (auto const& [idx, height]: arr | std::views::enumerate) {
std::println("{} {} {}", leftSmallerElements[idx], idx, rightSmallerElements[idx]);
auto width = rightSmallerElements[idx] - leftSmallerElements[idx] - 1;
maxArea = std::max(maxArea, height * width);
}
return maxArea;
}
int main() {
auto area = largestRectangleInHistogram({2, 1, 5, 6, 2, 3});
std::println("largestRectangleInHistogram area: {}", area);
}
Time complexity of UsingJumpPointers
is
Intuition: In this part of the code,
while (prevElemIdx != -1 && cmp(elem, arr[prevElemIdx])) {
prevElemIdx = prevElem[prevElemIdx];
}
Imagine that prevElemIdx
disappears from the array after this while loop runs. Everything else would still work, and each element can disappear atmost once. So, time complexity must be