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

📅  最后修改于: 2021-04-29 05:19:37             🧑  作者: Mango

给定大小为N + 1的只读数组arr [] ,请在该数组中找到多个重复元素之一,其中该数组仅包含1N之间的整数。
注意:只读数组表示无法修改数组的内容。

例子:

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

方法:该方法基于弗洛伊德的乌龟和野兔算法(循环检测算法)。

  1. 使用函数f(x)= arr [x]构造序列:
  2. 序列中的每个新元素都是arr []中前一个元素的索引处的元素。
  3. x = arr [0]开始,它将产生一个带有循环的链表。
  4. 之所以出现该循环,是因为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开始,遍历如下所示:

    序列形成循环,如下所示:

  5. 算法由两部分组成,并使用两个指针,通常称为tortoisehare
    • 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)