给定大小为N + 1的只读数组arr [] ,请在该数组中找到多个重复元素之一,其中该数组仅包含1到N之间的整数。
注意:只读数组表示无法修改数组的内容。
例子:
Input: N = 5, arr[] = {1, 1, 2, 3, 5, 4}
Output: 1
Explanation:
1 is the only number repeated in the array.
Input: N = 10, arr[] = {10, 1, 2, 3, 5, 4, 9, 8, 5, 6, 4}
Output: 5
Explanation:
5 is the one of the number repeated in the array.
在上一篇文章中,我们讨论了同一篇文章,其空间复杂度为O(N)和O(sqrt(N)) 。
方法:该方法基于弗洛伊德的乌龟和野兔算法(循环检测算法)。
- 使用函数f(x)= arr [x]构造序列:
arr[0], arr[arr[0]], arr[arr[arr[0]]], arr[arr[arr[arr[0]]]] …….
- 序列中的每个新元素都是arr []中前一个元素的索引处的元素。
- 从x = arr [0]开始,它将产生一个带有循环的链表。
- 之所以出现该循环,是因为arr []包含重复的元素(至少一个)。重复值是循环的入口。下面给出一个示例来显示周期如何存在:
例如:令数组arr [] = {2,6,4,1,1,3,1,5}
index 0 1 2 3 4 5 6 arr 2 6 4 1 3 1 5 从索引0开始,遍历如下所示:
arr[0] = 2 –> arr[2] = 4 –> arr[4] = 3 –> arr[3] = 1 –> arr[1] = 6 –> arr[6] = 5 –> arr[5] = 1.
序列形成循环,如下所示:
- 算法由两部分组成,并使用两个指针,通常称为tortoise和hare 。
- hare = arr [arr [hare]]的速度是tortoise = arr [tortoise]的两倍。
- 由于野兔跑得很快,它将是第一个进入循环并开始绕循环运行的人。
- 在某些时候,乌龟也会进入循环,因为它移动的速度较慢,所以兔子在某个交叉点将乌龟赶上了。
- 请注意,在一般情况下,交点不是自行车的入口,而是在自行车中间的某个地方相交。
- 将乌龟移动到序列的起点,并且兔子保持在周期内,并且都以相同的速度移动,即,乌龟= arr [陆龟]和hare = arr [野兔] 。现在它们在重复元素处相交。
下面是上述方法的实现:
C++
// C++ code for the above approach
#include
using namespace std;
// Function to find the duplicate
// value in the given array arr[]
void findDuplicate(int arr[])
{
// Initialise variables
int tortoise = arr[0];
int hare = arr[0];
// Loop till we find the
// duplicate element
while (1) {
tortoise = arr[tortoise];
// Hare moves with twice
// the speed of tortoise
hare = arr[arr[hare]];
if (tortoise == hare)
break;
}
tortoise = arr[0];
// Loop to get start point
// of the cycle as start
// point will be the duplicate
// element
while (tortoise != hare) {
tortoise = arr[tortoise];
hare = arr[hare];
}
// Print the duplicate element
cout << tortoise;
}
// Driver Code
int main()
{
// Given array
int arr[] = { 2, 6, 4, 1, 3, 1, 5 };
// Function Call
findDuplicate(arr);
return 0;
}
Java
// Java code for the above approach
class GFG{
// Function to find the duplicate
// value in the given array arr[]
static void findDuplicate(int arr[])
{
// Initialise variables
int tortoise = arr[0];
int hare = arr[0];
// Loop till we find the
// duplicate element
while (true)
{
tortoise = arr[tortoise];
// Hare moves with twice
// the speed of tortoise
hare = arr[arr[hare]];
if (tortoise == hare)
break;
}
tortoise = arr[0];
// Loop to get start point
// of the cycle as start
// point will be the duplicate
// element
while (tortoise != hare)
{
tortoise = arr[tortoise];
hare = arr[hare];
}
// Print the duplicate element
System.out.print(tortoise);
}
// Driver Code
public static void main (String []args)
{
// Given array
int arr[] = { 2, 6, 4, 1, 3, 1, 5 };
// Function Call
findDuplicate(arr);
}
}
// This code is contributed by chitranayal
Python3
# Python3 program for the above approach
# Function to find the duplicate
# value in the given array arr[]
def findDuplicate(arr):
# Initialise variables
tortoise = arr[0]
hare = arr[0]
# Loop till we find the
# duplicate element
while (1):
tortoise = arr[tortoise]
# Hare moves with twice
# the speed of tortoise
hare = arr[arr[hare]]
if (tortoise == hare):
break
tortoise = arr[0]
# Loop to get start point
# of the cycle as start
# point will be the duplicate
# element
while (tortoise != hare):
tortoise = arr[tortoise]
hare = arr[hare]
# Print the duplicate element
print (tortoise)
# Driver Code
# Given array
arr = [ 2, 6, 4, 1, 3, 1, 5 ]
# Function Call
findDuplicate(arr)
# This code is contributed by PratikBasu
C#
// C# program for the above approach
using System;
class GFG{
// Function to find the duplicate
// value in the given array []arr
static void findDuplicate(int []arr)
{
// Initialise variables
int tortoise = arr[0];
int hare = arr[0];
// Loop till we find the
// duplicate element
while (true)
{
tortoise = arr[tortoise];
// Hare moves with twice
// the speed of tortoise
hare = arr[arr[hare]];
if (tortoise == hare)
break;
}
tortoise = arr[0];
// Loop to get start point
// of the cycle as start
// point will be the duplicate
// element
while (tortoise != hare)
{
tortoise = arr[tortoise];
hare = arr[hare];
}
// Print the duplicate element
Console.Write(tortoise);
}
// Driver Code
public static void Main(String []args)
{
// Given array
int []arr = { 2, 6, 4, 1, 3, 1, 5 };
// Function Call
findDuplicate(arr);
}
}
// This code is contributed by Amit Katiyar
输出:
1
时间复杂度: O(N)
辅助空间: O(1)