Encuentre cualquiera de los múltiples elementos repetidos en una array de solo lectura

Dada una array de solo lectura de tamaño ( n+1 ), encuentre uno de los múltiples elementos repetidos en la array donde la array contiene números enteros solo entre 1 y n. 
Una array de solo lectura significa que el contenido de la array no se puede modificar.
Ejemplos: 

Input : n = 5
        arr[] = {1, 1, 2, 3, 5, 4}
Output : One of the numbers repeated in the array is: 1

Input : n = 10
        arr[] = {10, 1, 2, 3, 5, 4, 9, 8, 5, 6, 4}
Output : One of the numbers repeated in the array is: 4 OR 5

Método 1: dado que el tamaño de la array es n+1 y los elementos varían de 1 a n, se confirma que habrá al menos un elemento repetido. Una solución simple es crear una array de conteo y almacenar conteos de todos los elementos. Tan pronto como encontramos un elemento con un recuento de más de 1, lo devolvemos.

A continuación se muestra la implementación del enfoque anterior:

C++

// C++ program to find one of the repeating
// elements in a read only array
#include <bits/stdc++.h>
using namespace std;
 
// Function to find one of the repeating
// elements
int findRepeatingNumber(const int arr[], int n)
{
    for (int i = 0; i < n; i++) {
        int count = 0;
        for (int j = 0; j < n; j++) {
            if (arr[i] == arr[j])
                count++;
        }
        if (count > 1)
            return arr[i];
    }
    // If no repeating element exists
    return -1;
}
 
// Driver Code
int main()
{
    // Read only array
    const int arr[] = { 1, 1, 2, 3, 5, 4 };
 
    int n = 5;
 
    cout << "One of the numbers repeated in"
            " the array is: "
         << findRepeatingNumber(arr, n) << endl;
}

Java

public class GFG {
    // Java program to find one of the repeating
    // elements in a read only array
 
    // Function to find one of the repeating
    // elements
    public static int findRepeatingNumber(int[] arr, int n)
    {
        for (int i = 0; i < n; i++) {
            int count = 0;
            for (int j = 0; j < n; j++) {
                if (arr[i] == arr[j]) {
                    count++;
                }
            }
            if (count > 1) {
                return arr[i];
            }
        }
        // If no repeating element exists
        return -1;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        // Read only array
        final int[] arr = { 1, 1, 2, 3, 5, 4 };
 
        int n = 5;
 
        System.out.print("One of the numbers repeated in"
                         + " the array is: ");
        System.out.print(findRepeatingNumber(arr, n));
        System.out.print("\n");
    }
}
// This code is contributed by Aarti_Rathi

Python3

# Python 3program to find one of the repeating
# elements in a read only array
from math import sqrt
 
# Function to find one of the repeating
# elements
def findRepeatingNumber(arr, n):
     
    for i in arr:
      count = 0;
      for j in arr:
        if i == j:
          count=count+1
      if(count>1):
        return i
     
    # return -1 if no repeating element exists
    return -1
 
# Driver Code
if __name__ == '__main__':
     
    # read only array, not to be modified
    arr = [1, 1, 2, 3, 5, 4]
 
    # array of size 6(n + 1) having
    # elements between 1 and 5
    n = 5
 
    print("One of the numbers repeated in the array is:",
                             findRepeatingNumber(arr, n))
     
# This code is contributed by Arpit Jain

C#

// C# program to find one of the repeating
// elements in a read only array
using System;
 
public class GFG {
 
  // Function to find one of the repeating
  // elements
  public static int findRepeatingNumber(int[] arr, int n)
  {
    for (int i = 0; i < n; i++) {
      int count = 0;
      for (int j = 0; j < n; j++) {
        if (arr[i] == arr[j]) {
          count++;
        }
      }
      if (count > 1) {
        return arr[i];
      }
    }
    // If no repeating element exists
    return -1;
  }
 
  // Driver Code
  public static void Main(String[] args)
  {
    // Read only array
    int[] arr = { 1, 1, 2, 3, 5, 4 };
 
    int n = 5;
 
    Console.Write("One of the numbers repeated in"
                  + " the array is: ");
    Console.Write(findRepeatingNumber(arr, n));
    Console.Write("\n");
  }
}
 
// This code is contributed by Abhijeet Kumar(abhijeet19403)
Producción

One of the numbers repeated in the array is: 1

Tiempo Complejidad: O(n 2 )
Espacio Auxiliar: O(1)

Una solución optimizada para el espacio es dividir el rango dado (de 1 a n) en bloques de tamaño igual a sqrt(n). Mantenemos el recuento de elementos pertenecientes a cada bloque para cada bloque. Ahora, como el tamaño de una array es (n+1) y los bloques son de tamaño sqrt(n), entonces habrá uno de esos bloques cuyo tamaño será mayor que sqrt(n). Para el bloque cuyo recuento es mayor que sqrt(n), podemos usar hash para los elementos de este bloque para encontrar qué elemento aparece más de una vez. 
Explicación
el método descrito anteriormente funciona por los dos motivos siguientes: 

  1. Siempre habrá un bloque que tenga un recuento mayor que sqrt(n) debido a un elemento adicional. Incluso cuando se ha agregado un elemento adicional, ocupará una posición en uno de los bloques solamente, haciendo que ese bloque sea seleccionado.
  2. El bloque seleccionado definitivamente tiene un elemento repetitivo. Considere que el i -ésimo bloque está seleccionado. El tamaño del bloque es mayor que sqrt(n) (Por lo tanto, se selecciona) Máximo de elementos distintos en este bloque = sqrt(n). Por lo tanto, el tamaño puede ser mayor que sqrt(n) solo si hay un elemento repetido en el rango ( i*sqrt(n), (i+1)*sqrt(n) ].

Nota: El último bloque formado puede o no tener un rango igual a sqrt(n). Por lo tanto, verificar si este bloque tiene un elemento repetido será diferente a otros bloques. Sin embargo, esta dificultad se puede superar desde el punto de vista de la implementación inicializando el bloque seleccionado con el último bloque. Esto es seguro porque al menos un bloque tiene que ser seleccionado.
A continuación se muestra el algoritmo paso a paso para resolver este problema

  1. Divida la array en bloques de tamaño sqrt(n).
  2. Cree una array de conteo que almacene el conteo de elementos para cada bloque.
  3. Elija el bloque que tenga un recuento de más de sqrt(n), configurando el último bloque 
    como predeterminado.
  4. Para los elementos pertenecientes al bloque seleccionado, utilice el método de hashing (explicado en el siguiente paso) para encontrar el elemento repetido en ese bloque.
  5. Podemos crear una array hash de pares clave-valor, donde la clave es el elemento en el bloque y el valor es el recuento de la cantidad de veces que aparece la clave dada. Esto se puede implementar fácilmente usando unordered_map en C++ STL.

A continuación se muestra la implementación de la idea anterior:

C++

// C++ program to find one of the repeating
// elements in a read only array
#include <bits/stdc++.h>
using namespace std;
 
// Function to find one of the repeating
// elements
int findRepeatingNumber(const int arr[], int n)
{
    // Size of blocks except the
    // last block is sq
    int sq = sqrt(n);
 
    // Number of blocks to incorporate 1 to
    // n values blocks are numbered from 0
    // to range-1 (both included)
    int range = (n / sq) + 1;
 
    // Count array maintains the count for
    // all blocks
    int count[range] = {0};
 
    // Traversing the read only array and
    // updating count
    for (int i = 0; i <= n; i++)
    {
        // arr[i] belongs to block number
        // (arr[i]-1)/sq i is considered
        // to start from 0
        count[(arr[i] - 1) / sq]++;
    }
 
    // The selected_block is set to last
    // block by default. Rest of the blocks
    // are checked
    int selected_block = range - 1;
    for (int i = 0; i < range - 1; i++)
    {
        if (count[i] > sq)
        {
            selected_block = i;
            break;
        }
    }
 
    // after finding block with size > sq
    // method of hashing is used to find
    // the element repeating in this block
    unordered_map<int, int> m;
    for (int i = 0; i <= n; i++)
    {
        // checks if the element belongs to the
        // selected_block
        if ( ((selected_block * sq) < arr[i]) &&
                (arr[i] <= ((selected_block + 1) * sq)))
        {
            m[arr[i]]++;
 
            // repeating element found
            if (m[arr[i]] > 1)
                return arr[i];
        }
    }
 
    // return -1 if no repeating element exists
    return -1;
}
 
// Driver Program
int main()
{
    // read only array, not to be modified
    const int arr[] = { 1, 1, 2, 3, 5, 4 };
 
    // array of size 6(n + 1) having
    // elements between 1 and 5
    int n = 5;
 
    cout << "One of the numbers repeated in"
         " the array is: "
         << findRepeatingNumber(arr, n) << endl;
}

Java

// Java program to find one of the repeating
// elements in a read only array
import java.io.*;
import java.util.*;
 
class GFG
{
 
    // Function to find one of the repeating
    // elements
    static int findRepeatingNumber(int[] arr, int n)
    {
        // Size of blocks except the
        // last block is sq
        int sq = (int) Math.sqrt(n);
 
        // Number of blocks to incorporate 1 to
        // n values blocks are numbered from 0
        // to range-1 (both included)
        int range = (n / sq) + 1;
 
        // Count array maintains the count for
        // all blocks
        int[] count = new int[range];
 
        // Traversing the read only array and
        // updating count
        for (int i = 0; i <= n; i++)
        {
            // arr[i] belongs to block number
            // (arr[i]-1)/sq i is considered
            // to start from 0
            count[(arr[i] - 1) / sq]++;
        }
 
        // The selected_block is set to last
        // block by default. Rest of the blocks
        // are checked
        int selected_block = range - 1;
        for (int i = 0; i < range - 1; i++)
        {
            if (count[i] > sq)
            {
                selected_block = i;
                break;
            }
        }
 
        // after finding block with size > sq
        // method of hashing is used to find
        // the element repeating in this block
        HashMap<Integer, Integer> m = new HashMap<>();
        for (int i = 0; i <= n; i++)
        {
            // checks if the element belongs to the
            // selected_block
            if ( ((selected_block * sq) < arr[i]) &&
                    (arr[i] <= ((selected_block + 1) * sq)))
            {
                m.put(arr[i], 1);
 
                // repeating element found
                if (m.get(arr[i]) == 1)
                    return arr[i];
            }
        }
 
        // return -1 if no repeating element exists
        return -1;
}
 
// Driver code
public static void main(String args[])
{
    // read only array, not to be modified
    int[] arr = { 1, 1, 2, 3, 5, 4 };
 
    // array of size 6(n + 1) having
    // elements between 1 and 5
    int n = 5;
 
    System.out.println("One of the numbers repeated in the array is: " +
                                    findRepeatingNumber(arr, n));
}
}
 
// This code is contributed by rachana soma

Python3

# Python 3program to find one of the repeating
# elements in a read only array
from math import sqrt
 
# Function to find one of the repeating
# elements
def findRepeatingNumber(arr, n):
     
    # Size of blocks except the
    # last block is sq
    sq = sqrt(n)
 
    # Number of blocks to incorporate 1 to
    # n values blocks are numbered from 0
    # to range-1 (both included)
    range__= int((n / sq) + 1)
 
    # Count array maintains the count for
    # all blocks
    count = [0 for i in range(range__)]
 
    # Traversing the read only array and
    # updating count
    for i in range(0, n + 1, 1):
         
        # arr[i] belongs to block number
        # (arr[i]-1)/sq i is considered
        # to start from 0
        count[int((arr[i] - 1) / sq)] += 1
 
    # The selected_block is set to last
    # block by default. Rest of the blocks
    # are checked
    selected_block = range__ - 1
    for i in range(0, range__ - 1, 1):
        if (count[i] > sq):
            selected_block = i
            break
         
    # after finding block with size > sq
    # method of hashing is used to find
    # the element repeating in this block
    m = {i:0 for i in range(n)}
    for i in range(0, n + 1, 1):
         
        # checks if the element belongs
        # to the selected_block
        if (((selected_block * sq) < arr[i]) and
             (arr[i] <= ((selected_block + 1) * sq))):
            m[arr[i]] += 1
 
            # repeating element found
            if (m[arr[i]] > 1):
                return arr[i]
 
    # return -1 if no repeating element exists
    return -1
 
# Driver Code
if __name__ == '__main__':
     
    # read only array, not to be modified
    arr = [1, 1, 2, 3, 5, 4]
 
    # array of size 6(n + 1) having
    # elements between 1 and 5
    n = 5
 
    print("One of the numbers repeated in the array is:",
                             findRepeatingNumber(arr, n))
     
# This code is contributed by
# Sahil_shelangia

C#

// C# program to find one of the repeating
// elements in a read only array
using System;
using System.Collections.Generic;
 
class GFG
{
 
    // Function to find one of the repeating
    // elements
    static int findRepeatingNumber(int[] arr, int n)
    {
        // Size of blocks except the
        // last block is sq
        int sq = (int) Math.Sqrt(n);
 
        // Number of blocks to incorporate 1 to
        // n values blocks are numbered from 0
        // to range-1 (both included)
        int range = (n / sq) + 1;
 
        // Count array maintains the count for
        // all blocks
        int[] count = new int[range];
 
        // Traversing the read only array and
        // updating count
        for (int i = 0; i <= n; i++)
        {
            // arr[i] belongs to block number
            // (arr[i]-1)/sq i is considered
            // to start from 0
            count[(arr[i] - 1) / sq]++;
        }
 
        // The selected_block is set to last
        // block by default. Rest of the blocks
        // are checked
        int selected_block = range - 1;
        for (int i = 0; i < range - 1; i++)
        {
            if (count[i] > sq)
            {
                selected_block = i;
                break;
            }
        }
 
        // after finding block with size > sq
        // method of hashing is used to find
        // the element repeating in this block
        Dictionary<int,int> m = new Dictionary<int,int>();
        for (int i = 0; i <= n; i++)
        {
            // checks if the element belongs to the
            // selected_block
            if ( ((selected_block * sq) < arr[i]) &&
                    (arr[i] <= ((selected_block + 1) * sq)))
            {
                m.Add(arr[i], 1);
 
                // repeating element found
                if (m[arr[i]] == 1)
                    return arr[i];
            }
        }
 
        // return -1 if no repeating element exists
        return -1;
    }
 
// Driver code
public static void Main(String []args)
{
    // read only array, not to be modified
    int[] arr = { 1, 1, 2, 3, 5, 4 };
 
    // array of size 6(n + 1) having
    // elements between 1 and 5
    int n = 5;
 
    Console.WriteLine("One of the numbers repeated in the array is: " +
                                    findRepeatingNumber(arr, n));
}
}
 
// This code contributed by Rajput-Ji

Javascript

<script>
 
// JavaScript program to find one of the repeating
// elements in a read only array
 
 
// Function to find one of the repeating
// elements
function findRepeatingNumber(arr, n) {
    // Size of blocks except the
    // last block is sq
    let sq = Math.sqrt(n);
 
    // Number of blocks to incorporate 1 to
    // n values blocks are numbered from 0
    // to range-1 (both included)
    let range = Math.floor(n / sq) + 1;
 
    // Count array maintains the count for
    // all blocks
    let count = new Array(range).fill(0);
 
    // Traversing the read only array and
    // updating count
    for (let i = 0; i <= n; i++) {
        // arr[i] belongs to block number
        // (arr[i]-1)/sq i is considered
        // to start from 0
        count[Math.floor((arr[i] - 1) / sq)]++;
    }
 
    // The selected_block is set to last
    // block by default. Rest of the blocks
    // are checked
    let selected_block = range - 1;
    for (let i = 0; i < range - 1; i++) {
        if (count[i] > sq) {
            selected_block = i;
            break;
        }
    }
 
    // after finding block with size > sq
    // method of hashing is used to find
    // the element repeating in this block
    let m = new Map();
    for (let i = 0; i <= n; i++) {
        // checks if the element belongs to the
        // selected_block
        if (((selected_block * sq) < arr[i]) &&
            (arr[i] <= ((selected_block + 1) * sq))) {
            m[arr[i]]++;
 
            if (m.has(arr[i])) {
                m.set(arr[i], m.get(arr[i]) + 1)
            } else {
                m.set(arr[i], 1)
            }
 
            // repeating element found
            if (m.get(arr[i]) > 1)
                return arr[i];
        }
    }
 
    // return -1 if no repeating element exists
    return -1;
}
 
// Driver Program
 
// read only array, not to be modified
const arr = [1, 1, 2, 3, 5, 4];
 
// array of size 6(n + 1) having
// elements between 1 and 5
let n = 5;
 
document.write("One of the numbers repeated in"
    + " the array is: "
    + findRepeatingNumber(arr, n) + "<br>");
     
</script>
Producción

One of the numbers repeated in the array is: 1

Complejidad de tiempo : O(N) 
Espacio auxiliar : sqrt(N)

Este artículo es una contribución de Aanya Jindal . Si te gusta GeeksforGeeks y te gustaría contribuir, también puedes escribir un artículo usando write.geeksforgeeks.org o enviar tu artículo por correo a review-team@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks.
Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.
 

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *