diff --git a/matrix/binary_search_matrix.cpp b/matrix/binary_search_matrix.cpp new file mode 100644 index 000000000..9bc4f5832 --- /dev/null +++ b/matrix/binary_search_matrix.cpp @@ -0,0 +1,141 @@ +/** + * @file + * @brief [Binary Search in a 2d array](https://www.geeksforgeeks.org/searching-algorithms-for-a-2d-arrays-matrix/) + * in C++ + * @details + * Binary search is an efficient divide-and-conquer searching algorithm . + * It works by repeatedly dividing the search space in half, eliminating half of the elements each time, until the target element is found or it is determined that the element is not present in the array. + * It can only be applied to sorted matrixes(row-wise or column-wise). + * + * ### Complexities + * + * //n, m is the number rows and columns in the array. + * + * Worst-case time complexity O(log (n*m) + * Average time complexity O(log (n*m) + * Best-case time complexity O(1) + * Worst-case space complexity 0(1) + */ + +#include /// for IO operations +#include /// for std::vector +#include /// fro std::is_sorted +#include /// for assert + +template +std::vector binary_search_matrix(const std::vector>& matrix, const T& target){ + + if(matrix.empty() || matrix[0].empty()){ + return {-1, -1}; + } + + for (const auto& row : matrix) { + + if (!std::is_sorted(row.begin(), row.end())) { + return {-1, -1}; + } + } + + int m = matrix.size(); + int n = matrix[0].size(); + int i = 0, j = m*n-1; + + while(i <= j){ + + int mid = i + (j-i) / 2; + T midValue = matrix[mid/n][mid%n]; + + if(midValue == target){ + return {mid/n, mid%n}; + } + else if(midValue < target){ + i = mid + 1; + } + else{ + j = mid - 1; + } + } + + return {-1, -1}; +} + +/******************************************************************************* + * @brief Self-test implementation #1 + * @returns void + *******************************************************************************/ +static void test1() { + // testcase #1 + // array = [[1, 2, 3], + // [4, 5, 6], + // [7, 8, 9]] + // Value = 3 + // should return {0, 2} + + std::vector> intMatrix = { + {1, 2, 3}, + {4, 5, 6}, + {7, 8, 9} + }; + std::vector expected_ans = {2, 1}; + std::vector derived_ans = binary_search_matrix(intMatrix, 8); + std::cout << "Test #1: "; + assert(derived_ans == expected_ans); + std::cout << "Passed!" << std::endl; +} + +/******************************************************************************* + * @brief Self-test implementation #2 + * @returns void + *******************************************************************************/ +static void test2() { + // testcase #2 + // array = [[1.1, 2.2, 3.3], + // [4.4, 5.5, 6.6], + // [7.7, 8.8, 9.9] + // Value = 6.6 + // should return {1, 2} + + std::vector> doubleMatrix = { + {1.1, 2.2, 3.3}, + {4.4, 5.5, 6.6}, + {7.7, 8.8, 9.9} + }; + std::vector expected_ans = {0, 0}; + std::vector derived_ans = binary_search_matrix(doubleMatrix, 1.1); + std::cout << "Test #2: "; + assert(derived_ans == expected_ans); + std::cout << "Passed!" << std::endl; +} + +/******************************************************************************* + * @brief Self-test implementation #3 + * @returns void + *******************************************************************************/ +static void test3() { + // testcase #3 + // array = [['a', 'b', 'c'], + // ['f', 'e', 'd'], + // ['g', 'j', 'x'] + // Value = 'x' + // should return {2, 2} + + std::vector> charMatrix = { + {'a', 'b', 'c'}, + {'d', 'e', 'f'}, + {'g', 'h', 'i'} + }; + std::vector expected_ans = {2, 1}; + std::vector derived_ans = binary_search_matrix(charMatrix, 'h'); + std::cout << "Test #3: "; + assert(derived_ans == expected_ans); + std::cout << "Passed!" << std::endl; +} + +int main() { + + test1(); // run self-test implementation #1 + test2(); // run self-test implementation #2 + test3(); // run self-test implementation #3 + + return 0; +} diff --git a/matrix/linear_search_matrix.cpp b/matrix/linear_search_matrix.cpp new file mode 100644 index 000000000..42792cb35 --- /dev/null +++ b/matrix/linear_search_matrix.cpp @@ -0,0 +1,123 @@ +/** + * @file + * @brief [Linear Search in a 2d array](https://www.geeksforgeeks.org/searching-algorithms-for-a-2d-arrays-matrix/) + * in C++ + * @details + * Linear search is a simple and sequential searching algorithm. + * It is used to find whether a particular element is present in the array or not by traversing every element in the array. + * + * ### Complexities + * + * //n, m is the number rows and columns in the array. + * + * Worst-case time complexity O(n*m) => linear + * Average time complexity O(n*m) => linear + * Best-case time complexity O(1) => constant + * Worst-case space complexity 0(1) => constant + */ + +#include /// for IO operations +#include /// for std::vector +#include /// for assert + +template +std::vector linear_search_matrix(const std::vector>& matrix, const T& target){ + + if(matrix.empty() || matrix[0].empty()){ + return {-1, -1}; + } + + int rows = matrix.size(); + int columns = matrix[0].size(); + + for(int i = 0; i < rows; i++){ + for(int j = 0 ; j < columns; j++){ + if(matrix[i][j] == target){ + return {i, j}; + } + } + } + + return {-1, -1}; +} + +/******************************************************************************* + * @brief Self-test implementation #1 + * @returns void + *******************************************************************************/ +static void test1() { + // testcase #1 + // array = [[1, 2, 3], + // [4, 5, 6], + // [7, 8, 9]] + // Value = 3 + // should return {0, 2} + + std::vector> intMatrix = { + {1, 2, 3}, + {4, 5, 6}, + {7, 8, 9} + }; + std::vector expected_ans = {0, 2}; + std::vector derived_ans = linear_search_matrix(intMatrix, 3); + std::cout << "Test #1: "; + assert(derived_ans == expected_ans); + std::cout << "Passed!" << std::endl; +} + +/******************************************************************************* + * @brief Self-test implementation #2 + * @returns void + *******************************************************************************/ +static void test2() { + // testcase #2 + // array = [[1.1, 2.2, 3.3], + // [4.4, 5.5, 6.6], + // [7.7, 8.8, 9.9] + // Value = 6.6 + // should return {1, 2} + + std::vector> doubleMatrix = { + {1.1, 2.2, 3.3}, + {4.4, 5.5, 6.6}, + {12.6, 8.8, 9.9} + }; + std::vector expected_ans = {1, 2}; + std::vector derived_ans = linear_search_matrix(doubleMatrix, 6.6); + std::cout << "Test #2: "; + assert(derived_ans == expected_ans); + std::cout << "Passed!" << std::endl; +} + +/******************************************************************************* + * @brief Self-test implementation #3 + * @returns void + *******************************************************************************/ +static void test3() { + // testcase #3 + // array = [['a', 'b', 'c'], + // ['f', 'e', 'd'], + // ['g', 'j', 'x'] + // Value = 'x' + // should return {2, 2} + + std::vector> charMatrix = { + {'a', 'b', 'c'}, + {'f', 'e', 'd'}, + {'g', 'j', 'x'} + }; + std::vector expected_ans = {2, 2}; + std::vector derived_ans = linear_search_matrix(charMatrix, 'x'); + std::cout << "Test #3: "; + assert(derived_ans == expected_ans); + std::cout << "Passed!" << std::endl; +} + +int main() { + + test1(); // run self-test implementation #1 + test2(); // run self-test implementation #2 + test3(); // run self-test implementation #3 + + return 0; +}