|
1 |
| -# Floyd Cycle Detection Algorithm to find duplicate number in an array |
| 1 | +# Floyd Cycle Detection Algorithm to find duplicate numbers in an array |
2 | 2 |
|
3 | 3 | ## Problem Statement
|
4 | 4 |
|
5 | 5 | 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 without modifying the original array, otherwise, it returns -1.
|
6 | 6 |
|
7 | 7 | ## Approach
|
| 8 | +- We can imagine the array `arr` as a directed graph where each element is a node. `arr[i]` is the index of the node to which the i-th node points. |
| 9 | +- For example, given the `arr = [1, 3, 4, 2, 3]`, we can represent `arr` as the following <br></br> |
| 10 | + |
8 | 11 |
|
9 |
| -- Use the function `f(x) = arr[x]` to construct the sequence: |
10 |
| -`arr[0]`, `arr[arr[0]]`, `arr[arr[arr[0]]]`, `arr[arr[arr[arr[0]]]]`, etc.... |
11 |
| -- Each new element in the sequence is an element in `arr[]` at the index of the previous element. |
12 |
| -- Starting from `x = arr[0]`, it will produce a linked list with a cycle. |
13 |
| -- The cycle appears because `arr[]` contains duplicate elements(at least one). The duplicate value is an entrance to the cycle. |
| 12 | +- Since there are duplicates in `arr`, a cycle exists in the directed graph as there is a path from node 3 to itself, `3 -> 2 -> 4 -> 3`. |
| 13 | +- The problem now becomes finding the entrance node to the cycle (3 in this case). |
| 14 | +- We can use the Floyd Cycle Detection Algorithm (also known as the "Hare and Tortoise algorithm") to detect the entrance of the cycle. |
| 15 | +- The idea of the algorithm is to maintain two pointers, `hare` and `tortoise` that iterate the array at different "speeds" (just like the fable). The details are as follows: |
14 | 16 |
|
| 17 | +### The procedure |
| 18 | +- Using two pointers `hare` and `tortoise`. |
| 19 | +- Initiate `hare = tortoise = arr[0]`. |
| 20 | +- For every next step until `hare == tortoise` again, assign `hare = arr[arr[hare]]` and `tortoise = arr[tortoise]` (`hare` "jumps" 2 steps while `tortoise` "jumps" one step). |
| 21 | +- At this point, `hare == tortoise`, reset `tortoise = arr[0]` while keeping the value of `hare` in the above procedure. |
| 22 | +- For every next step until `hare == tortoise` again, assign `hare = arr[hare]` and `tortoise = arr[tortoise]` (this time `hare` only "jumps" one step). |
| 23 | +- When `tortoise == hare`, the entrance of the cycle is found, hence `hare` and `tortoise` represent the value of the duplicated element. |
| 24 | +- Return `tortoise` (also possible to return `hare`) |
| 25 | + |
15 | 26 | ## Time Complexity
|
16 | 27 |
|
17 |
| -O(n) |
| 28 | +`O(n)` |
18 | 29 |
|
19 | 30 | ## Space Complexity
|
20 | 31 |
|
21 |
| -O(1) |
| 32 | +`O(1)`, since we only use two extra variables as pointers. |
22 | 33 |
|
23 |
| -## Example |
| 34 | +## Example with step-by-step explanation |
| 35 | + |
24 | 36 |
|
25 | 37 | ```
|
26 |
| -arr = [3, 4, 8, 5, 9, 1, 2, 6, 7, 4] |
| 38 | +arr = [3, 4, 8, 5, 9, 1, 2, 6, 7, 4] |
27 | 39 |
|
28 |
| -return value = 4 |
| 40 | +hare = tortoise = arr[0] = 3 |
| 41 | +
|
| 42 | +1st step: |
| 43 | + - hare = arr[arr[3]] = arr[5] = 1 |
| 44 | + - tortoise = arr[3] = 5 |
| 45 | +2nd step: |
| 46 | + - hare = arr[arr[1]] = arr[4] = 9 |
| 47 | + - tortoise = arr[5] = 1 |
| 48 | +3rd step: |
| 49 | + - hare = arr[arr[9]] = arr[4] = 9 |
| 50 | + - tortoise = arr[1] = 4 |
| 51 | +4th step: |
| 52 | + - hare = arr[arr[9]] = 9 |
| 53 | + - tortoise = arr[4] = 9 |
| 54 | +
|
| 55 | +tortoise = arr[0] = 3 |
| 56 | +
|
| 57 | +1st step: |
| 58 | + - hare = arr[9] = 4 |
| 59 | + - tortoise = arr[3] = 5 |
| 60 | +2nd step: |
| 61 | + - hare = arr[4] = 9 |
| 62 | + - tortoise = arr[5] = 1 |
| 63 | +3rd step: |
| 64 | + - hare = arr[9] = 4 |
| 65 | + - tortoise = arr[1] = 4 |
| 66 | +
|
| 67 | +return tortoise = 4 |
29 | 68 | ```
|
30 | 69 |
|
31 | 70 | ## Code Implementation Links
|
32 | 71 |
|
33 | 72 | - [C++](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/search/floyd_cycle_detection_algo.cpp)
|
34 | 73 | - [C](https://github.com/TheAlgorithms/C/blob/master/searching/floyd_cycle_detection_algorithm.c)
|
35 |
| - |
36 | 74 | #### Video Explanation
|
37 | 75 |
|
38 |
| -[YouTube video explaining the Floyd Cycle Detection algorithm](https://www.youtube.com/watch?v=B6smdk7pZ14) |
| 76 | +- [YouTube video explaining the Floyd Cycle Detection algorithm](https://www.youtube.com/watch?v=B6smdk7pZ14) |
| 77 | +- [Another Youtube video](https://www.youtube.com/watch?v=PvrxZaH_eZ4&t=1s) |
0 commit comments