forked from TheAlgorithms/C-Plus-Plus
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add the floyd_cycle_detection_algo.cpp file/algorithm (TheAlgor…
…ithms#1540) * search for duplicate number using Floyd algorithm * Update floyd_cycle_detection_algo.cpp Co-authored-by: David Leal <[email protected]>
- Loading branch information
1 parent
652c2d2
commit 0e0ba5f
Showing
1 changed file
with
96 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 <cassert> /// for assert | ||
#include <iostream> /// for IO operations | ||
#include <vector> /// 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 <typename T> | ||
int32_t duplicateNumber(const std::vector<T> &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<uint32_t> 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<uint32_t> 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<uint32_t> 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; | ||
} |