📌  相关文章
📜  在只读数组中查找多个重复元素中的任意一个 | 2套

📅  最后修改于: 2021-10-25 04:57:28             🧑  作者: Mango

给定一个大小为N + 1的只读数组arr[] ,找到数组中多个重复元素之一,其中数组仅包含1N之间的整数。
注意:只读数组意味着数组的内容不能被修改。

例子:

在上一篇文章中,我们讨论了空间复杂度为O(N) 和 O(sqrt(N))的同一篇文章。

方法:这种方法基于弗洛伊德的龟兔赛跑算法( Cycle Detection Algorithm )。

  • 使用函数f(x) = arr[x]构造序列:
  • 序列中的每个新元素都是arr[]中前一个元素索引处的一个元素。
  • x = arr[0] 开始,它会产生一个带循环的链表。
  • 循环出现是因为arr[]包含重复元素(至少一个)。重复值是循环的入口。下面给出了一个例子来说明循环是如何存在的:
    例如:让数组 arr[] = {2, 6, 4, 1, 3, 1, 5}
index 0 1 2 3 4 5 6
arr 2 6 4 1 3 1 5

从索引 0 开始,遍历如下所示:

序列形成循环如下图:

  • 算法由两部分组成并使用两个指针,通常称为tortoisehare
  • hare = arr[arr[hare]]tortoise = arr[tortoise] 的两倍。
  • 由于兔子跑得很快,它会是第一个进入循环并开始绕着循环跑的人。
  • 在某些时候,乌龟也会进入循环,由于它移动得较慢,兔子在某个交叉点抓住了乌龟。
  • 请注意,在一般情况下,交点不是循环入口,而是两者在循环中间的某个地方相交。
  • 将乌龟移动到序列的起点,兔子保持在循环内,并且以相同的速度移动,即tortoise = arr[tortoise]hare = arr[hare] 。现在它们在重复元素处相交。

下面是上述方法的实现:

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


Javascript


输出:
1

时间复杂度: O(N)
辅助空间: O(1)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程