From 269bb657a61278d16cc87afdd35724807066e8b2 Mon Sep 17 00:00:00 2001 From: Manish Date: Mon, 27 Feb 2023 09:19:13 +1100 Subject: [PATCH] Design Pattern: 2. Islands (Matrix Traversal) | Problem: Number of Islands --- 2_num_of_islands.cpp | 98 ++++++++++++++++++++++++++++++++++++++++++++ CMakeLists.txt | 4 +- 2 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 2_num_of_islands.cpp diff --git a/2_num_of_islands.cpp b/2_num_of_islands.cpp new file mode 100644 index 0000000..f4c0220 --- /dev/null +++ b/2_num_of_islands.cpp @@ -0,0 +1,98 @@ +/* Problem source: https://leetcode.com/problems/number-of-islands/ + */ + +#include +#include +#include +#include +#include + +struct matrix_location { + unsigned c; // column + unsigned r; // row + bool operator==(const matrix_location &other) const { + return c == other.c && r == other.r; + }; +}; + +class matrix_location_hash { +private: + unsigned n_cols; + +public: + matrix_location_hash(const unsigned num_of_cols, const unsigned num_of_rows) + : n_cols(num_of_cols) { + if (num_of_rows > + std::numeric_limits::max() / num_of_cols) + throw "Grid too big, cannot represent all cells with unique number for " + "efficient hashing"; + }; + std::size_t operator()(const matrix_location &m) const { + unsigned long long cell = m.c + m.r * n_cols; + return std::hash()(cell); + } +}; + +unsigned num_of_islands(const std::vector> &grid) { + unsigned n_islands = 0; + matrix_location_hash ml_hash(grid.size(), + grid[0].size()); // FIXME: potential seg fault + std::unordered_set unexplored_land( + 10, ml_hash); + for (unsigned i = 0, columns = grid.size(); i < columns; i++) { + for (unsigned j = 0, rows = grid[i].size(); j < rows; j++) { + if (grid[i][j] == '0') { + } else if (grid[i][j] == '1') { + unexplored_land.insert({i, j}); + } else { + throw "Input grid cannot have elements other than '0' or '1'"; + } + } + } + while (unexplored_land.size()) { + for (auto &loc : unexplored_land) { + std::stack sub_explore({loc}); + bool island_added = false; + while (!sub_explore.empty()) { + matrix_location curr_loc = sub_explore.top(); + matrix_location above = {curr_loc.c - 1, curr_loc.r}, + left = {curr_loc.c, curr_loc.r - 1}, + right = {curr_loc.c, curr_loc.r + 1}, + below = {curr_loc.c + 1, curr_loc.r}; + sub_explore.pop(); + if (!island_added) { + n_islands++; + island_added = true; + } + if (unexplored_land.count(above)) { + sub_explore.push(above); + } + if (unexplored_land.count(left)) { + sub_explore.push(left); + } + if (unexplored_land.count(right)) { + sub_explore.push(right); + } + if (unexplored_land.count(below)) { + sub_explore.push(below); + } + unexplored_land.erase(curr_loc); + } + break; + } + } + return n_islands; +} + +int main() { + const std::vector> grid = {{'1', '1', '1', '1', '0'}, + {'1', '1', '0', '1', '0'}, + {'1', '1', '0', '0', '0'}, + {'0', '0', '0', '0', '0'}}, + grid2 = {{'1', '1', '0', '0', '0'}, + {'1', '1', '0', '0', '0'}, + {'0', '0', '1', '0', '0'}, + {'0', '0', '0', '1', '1'}}; + std::cout << num_of_islands(grid) << '\n' << num_of_islands(grid2) << "\n"; + return 0; +} diff --git a/CMakeLists.txt b/CMakeLists.txt index 03c52f2..d06b453 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,4 +7,6 @@ set(CMAKE_CXX_STANDARD_REQUIRED True) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror -g") -add_executable(1_longest_substring_with_k_distinct_characters 1_longest_substring_with_k_distinct_characters.cpp) \ No newline at end of file +add_executable(1_longest_substring_with_k_distinct_characters 1_longest_substring_with_k_distinct_characters.cpp) + +add_executable(2_num_of_islands 2_num_of_islands.cpp)