From 8c853f75d200c7012d21f161398fcafc78872758 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=BE=D1=80=D0=B5=D0=B2=20=D0=90=D0=BB=D0=B5=D0=BA?= =?UTF-8?q?=D1=81=D0=B0=D0=BD=D0=B4=D1=80?= Date: Mon, 16 Oct 2023 12:03:19 +0300 Subject: [PATCH] Maximal Rectangle --- CMakeLists.txt | 1 + solutions/maximal-rectangle/CMakeLists.txt | 1 + solutions/maximal-rectangle/solution.hpp | 38 ++++++++++++++++++++++ solutions/maximal-rectangle/test.cpp | 33 +++++++++++++++++++ 4 files changed, 73 insertions(+) create mode 100644 solutions/maximal-rectangle/CMakeLists.txt create mode 100644 solutions/maximal-rectangle/solution.hpp create mode 100644 solutions/maximal-rectangle/test.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 04d43e56..a4c3526d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -333,6 +333,7 @@ add_task(max-number-of-k-sum-pairs) add_task(max-pair-sum-in-an-array) add_task(max-points-on-a-line) add_task(maximal-network-rank) +add_task(maximal-rectangle) add_task(maximal-square) add_task(maximize-score-after-n-operations) add_task(maximize-the-confusion-of-an-exam) diff --git a/solutions/maximal-rectangle/CMakeLists.txt b/solutions/maximal-rectangle/CMakeLists.txt new file mode 100644 index 00000000..51d99e64 --- /dev/null +++ b/solutions/maximal-rectangle/CMakeLists.txt @@ -0,0 +1 @@ +add_catch(test_maximal_rectangle test.cpp) diff --git a/solutions/maximal-rectangle/solution.hpp b/solutions/maximal-rectangle/solution.hpp new file mode 100644 index 00000000..8cdc7208 --- /dev/null +++ b/solutions/maximal-rectangle/solution.hpp @@ -0,0 +1,38 @@ +#pragma once + +#include +#include + +class Solution { +public: + static int maximalRectangle(const std::vector> &matrix) { + const int n = matrix.size(), m = matrix.back().size(); + + int max_rectangle = 0; + std::vector heights(m); + for (int i = 0; i < n; ++i) { + for (int j = 0; j < m; ++j) { + heights[j] = matrix[i][j] == '0' ? 0 : heights[j] + 1; + } + max_rectangle = std::max(max_rectangle, largestRectangleArea(heights)); + } + return max_rectangle; + } + +private: + static int largestRectangleArea(const std::vector &heights) { + const int n = heights.size(); + std::stack stack; + int max_area = 0; + for (int i = 0; i <= n; ++i) { + while (!stack.empty() && (i == n || heights[stack.top()] > heights[i])) { + const auto height = heights[stack.top()]; + stack.pop(); + const auto width = stack.empty() ? i : i - stack.top() - 1; + max_area = std::max(max_area, height * width); + } + stack.push(i); + } + return max_area; + } +}; diff --git a/solutions/maximal-rectangle/test.cpp b/solutions/maximal-rectangle/test.cpp new file mode 100644 index 00000000..c3b0e69c --- /dev/null +++ b/solutions/maximal-rectangle/test.cpp @@ -0,0 +1,33 @@ +#include + +#include + +TEST_CASE("Simple") { + struct TestCase { + std::vector> matrix; + int expected; + }; + + std::vector test_cases{ + { + .matrix{{'1', '0', '1', '0', '0'}, + {'1', '0', '1', '1', '1'}, + {'1', '1', '1', '1', '1'}, + {'1', '0', '0', '1', '0'}}, + .expected = 6, + }, + { + .matrix{{'0'}}, + .expected = 0, + }, + { + .matrix{{'1'}}, + .expected = 1, + }, + }; + + for (const auto &[matrix, expected] : test_cases) { + const auto actual = Solution::maximalRectangle(matrix); + REQUIRE(expected == actual); + } +}