diff --git a/search/floyd_cycle_detection_algo.cpp b/search/floyd_cycle_detection_algo.cpp new file mode 100644 index 000000000..ac3d62769 --- /dev/null +++ b/search/floyd_cycle_detection_algo.cpp @@ -0,0 +1,96 @@ +/** + * @file + * @brief Implementation of [Floyd's Cycle + * Detection](https://en.wikipedia.org/wiki/Cycle_detection) algorithm + * @details + * Given an array of integers containing 'n + 1' integers, where each + * integer is in the range [1, n] inclusive. If there is only one duplicate + * number in the input array, this algorithm returns the duplicate number in + * O(1) space and the time complexity is less than O(n^2) without modifying the + * original array, otherwise, it returns -1. + * @author [Swastika Gupta](https://github.com/Swastyy) + */ + +#include /// for assert +#include /// for IO operations +#include /// for std::vector + +/** + * @namespace search + * @brief Search algorithms + */ +namespace search { +/** + * @namespace cycle_detection + * @brief Functions for the [Floyd's Cycle + * Detection](https://en.wikipedia.org/wiki/Cycle_detection) algorithm + */ +namespace cycle_detection { +/** + * @brief The main function implements search algorithm + * @tparam T type of array + * @param in_arr the input array + * @param n size of array + * @returns the duplicate number + */ +template +int32_t duplicateNumber(const std::vector &in_arr, const uint32_t &n) { + if (n == 0 || n == 1) { // to find duplicate in an array its size should be atleast 2 + return -1; + } + uint32_t tortoise = in_arr[0]; // variable tortoise is used for the longer + // jumps in the array + uint32_t hare = in_arr[0]; // variable hare is used for shorter jumps in the array + do { + tortoise = in_arr[tortoise]; + hare = in_arr[in_arr[hare]]; + } while (tortoise != hare); + tortoise = in_arr[0]; + while (tortoise != hare) { + tortoise = in_arr[tortoise]; + hare = in_arr[hare]; + } + return tortoise; +} +} // namespace cycle_detection +} // namespace search + +/** + * @brief Self-test implementations + * @returns void + */ +static void test() { + // 1st test + // [3, 4, 8, 5, 9, 1, 2, 6, 7, 4] return 4 + std::vector array1 = {3, 4, 8, 5, 9, 1, 2, 6, 7, 4}; + std::cout << "Test 1... "; + assert(search::cycle_detection::duplicateNumber(array1, array1.size()) == + 4); // here the duplicate number is 4 + std::cout << "passed" << std::endl; + + // 2nd test + // [1, 2, 3, 4, 2] return 2 + std::vector array2 = {1, 2, 3, 4, 2}; + std::cout << "Test 2... "; + assert(search::cycle_detection::duplicateNumber(array2, array2.size()) == + 2); // here the duplicate number is 2 + std::cout << "passed" << std::endl; + + // 3rd test + // [] return -1 + std::vector array3 = {}; + std::cout << "Test 3... "; + assert(search::cycle_detection::duplicateNumber(array3, array3.size()) == + -1); // since the input array is empty no duplicate number exists in + // this case + std::cout << "passed" << std::endl; +} + +/** + * @brief Main function + * @returns 0 on exit + */ +int main() { + test(); // run self-test implementations + return 0; +}