/** * @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; }