Как найти повторяющиеся цифры в массиве

Given an array of n integers. The task is to print the duplicates in the given array. If there are no duplicates then print -1. 

Examples: 

Input: {2, 10,10, 100, 2, 10, 11,2,11,2}
Output: 2 10 11

Input: {5, 40, 1, 40, 100000, 1, 5, 1}
Output: 5 40 1

Note: The duplicate elements can be printed in any order.

Simple Approach: The idea is to use nested loop and for each element check if the element is present in the array more than once or not. If present, then store it in a Hash-map. Otherwise, continue checking other elements.

Below is the implementation of the above approach:

C++

#include <bits/stdc++.h>

using namespace std;

void findDuplicates(int arr[], int len)

{

    bool ifPresent = false;

    vector<int> al;

    for(int i = 0; i < len - 1; i++)

    {

        for(int j = i + 1; j < len; j++)

        {

            if (arr[i] == arr[j])

            {

                auto it = std::find(al.begin(),

                                    al.end(), arr[i]);

                if (it != al.end())

                {

                    break;

                }

                else

                {

                    al.push_back(arr[i]);

                    ifPresent = true;

                }

            }

        }

    }

    if (ifPresent == true)

    {

        cout << "[" << al[0] << ", ";

        for(int i = 1; i < al.size() - 1; i++)

        {

            cout << al[i] << ", ";

        }

        cout << al[al.size() - 1] << "]";

    }

    else

    {

        cout << "No duplicates present in arrays";

    }

}

int main()

{

    int arr[] = { 12, 11, 40, 12,

                  5, 6, 5, 12, 11 };

    int n = sizeof(arr) / sizeof(arr[0]);

    findDuplicates(arr, n);

    return 0;

}

Java

import java.util.ArrayList;

public class GFG {

    static void findDuplicates(

      int arr[], int len)

    {

        boolean ifPresent = false;

        ArrayList<Integer> al = new ArrayList<Integer>();

        for (int i = 0; i < len - 1; i++) {

            for (int j = i + 1; j < len; j++) {

                if (arr[i] == arr[j]) {

                    if (al.contains(arr[i])) {

                        break;

                    }

                    else {

                        al.add(arr[i]);

                        ifPresent = true;

                    }

                }

            }

        }

        if (ifPresent == true) {

            System.out.print(al + " ");

        }

        else {

            System.out.print(

                "No duplicates present in arrays");

        }

    }

    public static void main(String[] args)

    {

        int arr[] = { 12, 11, 40, 12, 5, 6, 5, 12, 11 };

        int n = arr.length;

        findDuplicates(arr, n);

    }

}

Python3

def findDuplicates(arr, Len):

    ifPresent = False

    a1 = []

    for i in range(Len - 1):

        for j in range(i + 1, Len):

            if (arr[i] == arr[j]):

                if arr[i] in a1:

                    break

                else:

                    a1.append(arr[i])

                    ifPresent = True

    if (ifPresent):

        print(a1, end = " ")

    else:

        print("No duplicates present in arrays")

arr = [ 12, 11, 40, 12, 5, 6, 5, 12, 11 ]

n = len(arr)

findDuplicates(arr, n)

C#

using System;

using System.Collections.Generic;

class GFG{

static void findDuplicates(int[] arr, int len)

{

    bool ifPresent = false;

    List<int> al = new List<int>();

    for(int i = 0; i < len - 1; i++)

    {

        for(int j = i + 1; j < len; j++)

        {

            if (arr[i] == arr[j])

            {

                if (al.Contains(arr[i]))

                {

                    break;

                }

                else

                {

                    al.Add(arr[i]);

                    ifPresent = true;

                }

            }

        }

    }

    if (ifPresent == true)

    {

        Console.Write("[" + al[0] + ", ");

        for(int i = 1; i < al.Count - 1; i++)

        {

            Console.Write(al[i] + ", ");

        }

        Console.Write(al[al.Count - 1] + "]");

    }

    else

    {

        Console.Write("No duplicates present in arrays");

    }

}

static void Main()

{

    int[] arr = { 12, 11, 40, 12,

                  5, 6, 5, 12, 11 };

    int n = arr.Length;

    findDuplicates(arr, n);

}

}

Javascript

<script>

function findDuplicates(arr, len) {

    let ifPresent = false;

    let al = new Array();

    for (let i = 0; i < len - 1; i++) {

        for (let j = i + 1; j < len; j++) {

            if (arr[i] == arr[j]) {

                if (al.includes(arr[i])) {

                    break;

                }

                else {

                    al.push(arr[i]);

                    ifPresent = true;

                }

            }

        }

    }

    if (ifPresent == true) {

        document.write(`[${al}]`);

    }

    else {

        document.write("No duplicates present in arrays");

    }

}

let arr = [12, 11, 40, 12, 5, 6, 5, 12, 11];

let n = arr.length;

findDuplicates(arr, n);

</script>

Time Complexity: O(N2
Auxiliary Space: O(N)

Efficient Approach: Use unordered_map for hashing. Count frequency of occurrence of each element and the elements with frequency more than 1 is printed. unordered_map is used as range of integers is not known. For Python, Use Dictionary to store number as key and it’s frequency as value. Dictionary can be used as range of integers is not known.

Below is the implementation of the above approach:

C++

#include <bits/stdc++.h>

using namespace std;

void printDuplicates(int arr[], int n)

{

    unordered_map<int, int> freq;

    for (int i=0; i<n; i++)

        freq[arr[i]]++;

    bool dup = false;

    unordered_map<int, int>:: iterator itr;

    for (itr=freq.begin(); itr!=freq.end(); itr++)

    {

        if (itr->second > 1)

        {

            cout << itr->first << " ";

            dup = true;

        }

    }

    if (dup == false)

        cout << "-1";

}

int main()

{

    int arr[] = {12, 11, 40, 12, 5, 6, 5, 12, 11};

    int n = sizeof(arr) / sizeof(arr[0]);

    printDuplicates(arr, n);

    return 0;

}

Java

import java.util.HashMap;

import java.util.Map;

import java.util.Map.Entry;

public class FindDuplicatedInArray

{

    public static void main(String[] args)

    {

        int arr[] = {12, 11, 40, 12, 5, 6, 5, 12, 11};

        int n = arr.length;

        printDuplicates(arr, n);

    }

    private static void printDuplicates(int[] arr, int n)

    {

        Map<Integer,Integer> map = new HashMap<>();

        int count = 0;

        boolean dup = false;

        for(int i = 0; i < n; i++){

            if(map.containsKey(arr[i])){

                count = map.get(arr[i]);

                map.put(arr[i], count + 1);

            }

            else{

                map.put(arr[i], 1);

            }

        }

        for(Entry<Integer,Integer> entry : map.entrySet())

        {

            if(entry.getValue() > 1){

                System.out.print(entry.getKey()+ " ");

                dup = true;

            }

        }

        if(!dup){

            System.out.println("-1");

        }

    }

}

Python3

def printDuplicates(arr):

    dict = {}

    for ele in arr:

        try:

            dict[ele] += 1

        except:

            dict[ele] = 1

    for item in dict:

        if(dict[item] > 1):

            print(item, end=" ")

    print("n")

if __name__ == "__main__":

    list = [12, 11, 40, 12,

            5, 6, 5, 12, 11]

    printDuplicates(list)

C#

using System;

using System.Collections.Generic;

class GFG

{

    static void printDuplicates(int[] arr, int n)

    {

        Dictionary<int,

                   int> map = new Dictionary<int,

                                             int>();

        int count = 0;

        bool dup = false;

        for (int i = 0; i < n; i++)

        {

            if (map.ContainsKey(arr[i]))

            {

                count = map[arr[i]];

                map[arr[i]]++;

            }

            else

                map.Add(arr[i], 1);

        }

        foreach (KeyValuePair<int,

                              int> entry in map)

        {

            if (entry.Value > 1)

                Console.Write(entry.Key + " ");

            dup = true;

        }

        if (!dup)

            Console.WriteLine("-1");

    }

    public static void Main(String[] args)

    {

        int[] arr = { 12, 11, 40, 12,

                     5, 6, 5, 12, 11 };

        int n = arr.Length;

        printDuplicates(arr, n);

    }

}

Javascript

<script>

function printDuplicates(arr, n)

{

    var freq = new Map();

    for(let i = 0; i < n; i++)

    {

        if (freq.has(arr[i]))

        {

            freq.set(arr[i], freq.get(arr[i]) + 1);

        }

        else

        {

            freq.set(arr[i], 1);

        }

    }

    var dup = false;

    for(let [key, value] of freq)

    {

        if (value > 1)

        {

            document.write(key + " ");

            dup = true;

        }

    }

    if (dup == false)

        document.write("-1");

}

var arr = [ 12, 11, 40, 12,

            5, 6, 5, 12, 11 ];

var n = arr.length;

printDuplicates(arr, n);

</script>

Time Complexity: O(N)
Auxiliary Space: O(N)   

Another Efficient Approach(Space optimization):            

  • First we will sort the array for binary search function.
  • we will find index at which arr[i] occur first time lower_bound 
  • Then , we will find index at which arr[i] occur last time upper_bound            
  • Then check if diff=(last_index-first_index+1)>1         
  • If diff >1 means it occurs more than once and print                         

 Below is the implementation of the above approach:

C++

#include <bits/stdc++.h>

using namespace std;

void printDuplicates(int arr[], int n)

{  

    sort(arr,arr+n);

    cout<<"[";

    for(int i = 0 ; i < n ;i++)

    {

      int first_index = lower_bound(arr,arr+n,arr[i])- arr;

      int last_index = upper_bound(arr,arr+n,arr[i])- arr-1;

      int occur_time = last_index-first_index+1;

      if(occur_time > 1 )

      {  i=last_index;

       cout<<arr[i]<<", ";  }

    }   cout<<"]";

}

int main()

{   int arr[] = {12, 11, 40, 12, 5, 6, 5, 12, 11};

    int n = sizeof(arr) / sizeof(arr[0]);

    printDuplicates(arr, n);

    return 0;

}

Python3

def printDuplicates(arr, n):

    arr.sort() 

    print("[", end="") 

    i = 0 

    while i < n:

        first_index = arr.index(arr[i])

        last_index = n - arr[::-1].index(arr[i]) - 1

        occur_time = last_index - first_index + 1 

        if occur_time > 1

            i = last_index 

            print(arr[i], end=", "

        i += 1 

    print("]"

arr = [12, 11, 40, 12, 5, 6, 5, 12, 11]

n = len(arr)

printDuplicates(arr, n)

Java

import java.io.*;

import java.util.*;

class GFG {

    public static int lowerBound(int[] arr, int target)

    {

        int lo = 0, hi = arr.length - 1;

        int ans = -1;

        while (lo <= hi) {

            int mid = lo + (hi - lo) / 2;

            if (arr[mid] >= target) {

                ans = mid;

                hi = mid - 1;

            }

            else {

                lo = mid + 1;

            }

        }

        return ans;

    }

    public static int upperBound(int[] arr, int target)

    {

        int lo = 0, hi = arr.length - 1;

        int ans = -1;

        while (lo <= hi) {

            int mid = lo + (hi - lo) / 2;

            if (arr[mid] <= target) {

                ans = mid;

                lo = mid + 1;

            }

            else {

                hi = mid - 1;

            }

        }

        return ans;

    }

    static void printDuplicates(int[] arr, int n)

    {

        Arrays.sort(arr);

        System.out.print("[");

        for (int i = 0; i < n; i++) {

            int firstIndex = lowerBound(arr, arr[i]);

            int lastIndex = upperBound(arr, arr[i]);

            int occurTime = lastIndex - firstIndex

                            + 1;

            if (occurTime

                > 1) {

                i = lastIndex;

                System.out.print(arr[i] + ", ");

            }

        }

        System.out.println("]");

    }

    public static void main(String[] args)

    {

        int[] arr = { 12, 11, 40, 12, 5, 6, 5, 12, 11 };

        int n = arr.length;

        printDuplicates(arr, n);

    }

}

Javascript

function printDuplicates(arr, n) {

    arr.sort();

    console.log("[");

    for (let i = 0; i < n; i++)

    {

        let first_index = arr.indexOf(arr[i]);

        let last_index = arr.lastIndexOf(arr[i]);

        let occur_time = last_index - first_index + 1;

        if (occur_time > 1) {

            i = last_index;

            console.log(arr[i] + ", ");

        }

    }

    console.log("]");

}

let arr = [12, 11, 40, 12, 5, 6, 5, 12, 11];

let n = arr.length;

printDuplicates(arr, n);

C#

using System;

class MainClass {

    static void printDuplicates(int[] arr, int n) {

        Array.Sort(arr);

        Console.Write("[");

        for (int i = 0; i < n; i++) {

            int first_index = Array.IndexOf(arr, arr[i]);

            int last_index = Array.LastIndexOf(arr, arr[i]);

            int occur_time = last_index - first_index + 1;

            if (occur_time > 1) {

                i = last_index;

                Console.Write(arr[i] + ", ");

            }

        }

        Console.Write("]");

    }

    static void Main() {

        int[] arr = {12, 11, 40, 12, 5, 6, 5, 12, 11};

        int n = arr.Length;

        printDuplicates(arr, n);

    }

}

Time Complexity: O(n*log2n)
Auxiliary Space: O(1)

Related Post : 
Print All Distinct Elements of a given integer array 
Find duplicates in O(n) time and O(1) extra space | Set 1 
Duplicates in an array in O(n) and by using O(1) extra space | Set-2 
Print all the duplicates in the input string

This article is contributed by Ayush Jauhari. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Last Updated :
18 Apr, 2023

Like Article

Save Article

Один из способов решения этой задачи – использовать словарь. Можно создать словарь, в котором каждому элементу списка соответствует количество его повторений, и в цикле перебрать элементы списка, добавляя их в словарь.

Вот пример такой функции:

def count_repeats(lst):
    """
    Возвращает словарь, в котором каждому элементу списка lst соответствует
    количество его повторений.
    """
    repeats = {}
    for item in lst:
        if item in repeats:
            repeats[item] += 1
        else:
            repeats[item] = 1
    return repeats



# Пример использования функции
lst = [10, 10, 23, 10, 123, 66, 78, 123]
repeats = count_repeats(lst)
print(repeats)  # {10: 3, 123: 2}

Функция count_repeats принимает на вход список lst, перебирает его элементы и добавляет их в словарь repeats. Если элемент уже есть в словаре, то увеличивается значение соответствующей пары ключ-значение, если же элемента еще нет в словаре, то добавляется пара с ключом равным этому элементу и значением 1.

Вы можете использовать эту функцию, чтобы найти повторяющиеся элементы в списке и количество их повторений.


Вы также можете использовать функцию Counter из модуля collections, чтобы посчитать количество повторений элементов списка. Эта функция возвращает словарь, в котором каждому элементу списка соответствует количество его повторений.

Вот пример кода, который использует функцию Counter:

from collections import Counter

def count_repeats(lst):
    """
    Возвращает словарь, в котором каждому элементу списка lst соответствует
    количество его повторений.
    """
    return Counter(lst)


# Пример использования функции
lst = [10, 10, 23, 10, 123, 66, 78, 123]
repeats = count_repeats(lst)
print(repeats)  # Counter({10: 3, 123: 2})

В этом коде сначала импортируется модуль collections и функция Counter, а затем определяется функция count_repeats, которая принимает список lst и возвращает результат вызова функции Counter на этом списке.


Вы также можете использовать функцию most_common из модуля collections, чтобы найти топ-N самых часто встречающихся элементов в списке. Эта функция принимает список и число N, и возвращает список кортежей, каждый из которых содержит элемент и количество его повторений.

Вот пример кода, который использует функцию most_common:

from collections import Counter

def find_top_repeats(lst, n):
    """
    Возвращает топ-N самых часто встречающихся элементов в списке lst.
    """
    return Counter(lst).most_common(n)


# Пример использования функции
lst = [10, 10, 23, 10, 123, 66, 78, 123]
top_repeats = find_top_repeats(lst, 2)
print(top_repeats)  # [(10, 3), (123, 2)]

В этом коде сначала импортируется модуль collections и функция Counter, а затем определяется функция find_top_repeats, которая принимает список lst и число n, и возвращает результат вызова функции most_common


Если вам нужно найти только уникальные элементы в списке, то можете использовать функцию set. Эта функция создает множество из элементов списка, удаляя повторяющиеся элементы. Множество не содержит повторяющихся элементов, поэтому вы можете использовать его, чтобы найти уникальные элементы в списке.

Вот пример кода, который использует функцию set:

def find_unique(lst):
    """
    Возвращает список уникальных элементов в списке lst.
    """
    return list(set(lst))


# Пример использования функции
lst = [10, 10, 23, 10, 123, 66, 78, 123]
unique = find_unique(lst)
print(unique)  # [66, 78, 10, 123, 23]

В этом коде определяется функция find_unique, которая принимает список lst и возвращает список уникальных элементов. Для этого список преобразуется в множество


Если вам нужно найти только уникальные элементы в списке и посчитать их количество, то можете соединить два предыдущих подхода: сначала использовать функцию set для нахождения уникальных элементов, а затем функцию count_repeats для подсчета их количества.

Вот пример кода, который реализует этот подход:

def count_unique(lst):
    """
    Возвращает словарь, в котором каждому уникальному элементу списка lst соответствует
    количество его повторений.
    """
    repeats = {}
    for item in set(lst):
        repeats[item] = lst.count(item)
    return repeats


# Пример использования функции
lst = [10, 10, 23, 10, 123, 66, 78, 123]
unique_counts = count_unique(lst)
print(unique_counts)  # {66: 1, 78: 1, 10: 3, 123: 2}

В этом коде определяется функция count_unique, которая принимает список lst и возвращает словарь, в котором каждому уникальному элементу списка

#статьи

  • 23 янв 2023

  • 0

Задача: проверить массив на дубликаты

Решаем задачи, которые дают программистам на собеседованиях в IT-компаниях. Сегодня ищем в массиве повторяющиеся элементы.

Иллюстрация: Polina Vari для Skillbox Media

Дмитрий Зверев

Любитель научной фантастики и технологического прогресса. Хорошо сочетает в себе заумного технаря и утончённого гуманитария. Пишет про IT и радуется этому.


Условие. Дан массив целых чисел — nums. Необходимо написать функцию, которая возвращает true, если в этом массиве хотя бы одно число повторяется дважды. Если же все элементы уникальны, функция должна вернуть false.

Ввод: nums = [1,2,3,1]
Вывод: true

Ввод: nums = [1,2,3,4]
Вывод: false

Ввод: nums = [1,1,1,3,3,4,3,2,4,2]
Вывод: true

Решить эту задачу самостоятельно и на разных языках программирования можно на LeetCode. Наше решение взято из телеграм-канала Сергея Cracking code interview.

Решение

При решении подобных задач важно выбрать подходящий тип данных. Здесь мы исходим из такой логики: «повторяется дважды» → значит, ищем дубликаты. Следовательно, выбираем множество (set).

Мы создадим пустое множество и будем обходить весь массив, просто проверяя, находится ли элемент во множестве:

  • если он ещё не находится — добавляем его;
  • если элемент уже там — значит, мы встретили повторяющийся элемент и просто возвращаем true.

public boolean containsDuplicate(int[] nums) {
    Set<Integer> set = new HashSet<>();
    for (int i : nums) {
        if (set.contains(i)) {
            return true;
        } else {
            set.add(i);
        }
    }
    return false;
}

Результаты

Временная сложность: O(n) — так как в самом плохом случае мы проходимся по всему массиву.

Ёмкостная сложность: O(1) — нам нужно заранее определённое количество места в памяти.

Научитесь: Профессия Java-разработчик
Узнать больше

Учитывая ограниченный диапазон размеров массива n содержащие элементы от 1 до n-1 с повторяющимся элементом найдите в нем повторяющийся номер, не используя лишнего пробела.

Например,

Input:  { 1, 2, 3, 4, 4 }
Output: The duplicate element is 4

 
 
Input:  { 1, 2, 3, 4, 2 }
Output: The duplicate element is 2

Потренируйтесь в этой проблеме

Подход 1: Использование хеширования

Идея состоит в том, чтобы использовать Хеширование Для решения этой проблемы. Мы можем использовать посещенный логический массив, чтобы отметить, был ли элемент замечен ранее или нет. Если элемент уже встречался ранее, посещенный массив вернет значение true.

Ниже приведена реализация на C++, Java и Python, основанная на приведенной выше идее:

C++

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

#include <iostream>

#include <vector>

using namespace std;

// Функция для поиска повторяющегося элемента в массиве с ограниченным диапазоном

int findDuplicate(vector<int> const &nums)

{

    int n = nums.size();

    // создаем посещаемый массив размером `n+1`

    // мы также можем использовать карту вместо посещаемого массива

    vector<bool> visited(n + 1);

    // помечаем каждый элемент массива как посещенный и

    // возвращаем его, если видели раньше

    for (int i: nums)

    {

        // если элемент был замечен раньше

        if (visited[i]) {

            return i;

        }

        // отметить элемент как посещенный

        visited[i] = true;

    }

    // дубликат не найден

    return 1;

}

int main()

{

    // входной массив содержит `n` чисел от 1 до `n-1` с одним дубликатом

    vector<int> nums = { 1, 2, 3, 4, 4 };

    cout << “The duplicate element is “ << findDuplicate(nums);

    return 0;

}

Скачать  Выполнить код

результат:

The duplicate element is 4

Java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

class Main

{

    // Функция для поиска повторяющегося элемента в массиве с ограниченным диапазоном

    public static int findDuplicate(int[] nums)

    {

        // создаем посещаемый массив размером `n+1`

        // мы также можем использовать карту вместо посещаемого массива

        boolean visited[] = new boolean[nums.length + 1];

        // помечаем каждый элемент массива как посещенный и

        // возвращаем его, если видели раньше

        for (int value: nums)

        {

            // если элемент был замечен раньше

            if (visited[value]) {

                return value;

            }

            // отметить элемент как посещенный

            visited[value] = true;

        }

        // дубликат не найден

        return 1;

    }

    public static void main (String[] args)

    {

        // входной массив содержит `n` чисел от 1 до `n-1`

        // с одним дубликатом, где `n` – длина массива

        int[] nums = { 1, 2, 3, 4, 4 };

        System.out.println(“The duplicate element is “ + findDuplicate(nums));

    }

}

Скачать  Выполнить код

результат:

The duplicate element is 4

Python

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

# Функция поиска повторяющегося элемента в списке с ограниченным диапазоном

def findDuplicate(nums):

    # создает список посещений размером `n+1`

    # мы также можем использовать словарь вместо списка посещенных

    visited = [False] * (len(nums) + 1)

    # для каждого элемента в списке, отметить его как посещенный и

    # верните его, если видели раньше

    for i in nums:

        #, если элемент был замечен раньше

        if visited[i]:

            return i

        # пометить элемент как посещенный

        visited[i] = True

    # дубликат не найден

    return 1

if __name__ == ‘__main__’:

    # список ввода содержит `n` чисел от 1 до `n-1`

    # с одним дубликатом, где `n = len(nums)`

    nums = [1, 2, 3, 4, 4]

    print(‘The duplicate element is’, findDuplicate(nums))

Скачать  Выполнить код

результат:

The duplicate element is 4

Временная сложность приведенного выше решения равна O(n) и требует O(n) дополнительное пространство, где n это размер ввода.

Подход 2: Использование индексов массива

Мы можем решить эту задачу в постоянном пространстве. Поскольку массив содержит все отдельные элементы, кроме одного, и все элементы лежат в диапазоне от 1 до n-1, мы можем проверить наличие повторяющегося элемента, пометив элементы массива как отрицательные, используя индекс массива в качестве ключа. Для каждого элемента массива nums[i], инвертировать знак элемента, присутствующего в индексе nums[i]. Наконец, еще раз пройдитесь по массиву, и если в индексе будет найдено положительное число i, то повторяющийся элемент i.

Приведенный выше подход требует двух обходов массива. Мы можем добиться того же только за один проход. Для каждого элемента массива nums[i], инвертировать знак элемента, присутствующего в индексе nums[i] если он положительный; в противном случае, если элемент уже отрицательный, то это дубликат.

Алгоритм может быть реализован следующим образом на C++, Java и Python:

C++

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

#include <iostream>

#include <vector>

using namespace std;

// Функция для поиска повторяющегося элемента в массиве с ограниченным диапазоном

int findDuplicate(vector<int> &nums)

{

    int duplicate = 1;

    // делаем для каждого элемента массива

    for (int i = 0; i < nums.size(); i++)

    {

        // получаем значение текущего элемента

        int val = abs(nums[i]);

        // сделать элемент с индексом val отрицательным, если он положительный

        if (nums[val] >= 0) {

            nums[val] = nums[val];

        }

        else {

            // если элемент уже отрицательный, он повторяется

            duplicate = val;

            break;

        }

    }

    // восстанавливаем исходный массив перед возвратом

    for (int i = 0; i < nums.size(); i++)

    {

        // сделать отрицательные элементы положительными

        if (nums[i] < 0) {

            nums[i] = nums[i];

        }

    }

    // возвращаем повторяющийся элемент

    return duplicate;

}

int main()

{

    // входной массив содержит `n` чисел от 1 до `n-1`

    // с одним дубликатом

    vector<int> nums = { 1, 2, 3, 4, 2 };

    cout << “The duplicate element is “ << findDuplicate(nums);

    return 0;

}

Скачать  Выполнить код

результат:

The duplicate element is 2

Java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

class Main

{

    // Функция для поиска повторяющегося элемента в массиве с ограниченным диапазоном

    public static int findDuplicate(int[] nums)

    {

        int duplicate = 1;

        // делаем для каждого элемента массива

        for (int i: nums)

        {

            // получаем значение текущего элемента

            int val = (i < 0) ? i : i;

            // сделать элемент с индексом val отрицательным, если он положительный

            if (nums[val] >= 0) {

                nums[val] = nums[val];

            }

            else {

                // если элемент уже отрицательный, он повторяется

                duplicate = val;

                break;

            }

        }

        // восстанавливаем исходный массив перед возвратом

        for (int i = 0; i < nums.length; i++)

        {

            // сделать отрицательные элементы положительными

            if (nums[i] < 0) {

                nums[i] = nums[i];

            }

        }

        // возвращаем повторяющийся элемент

        return duplicate;

    }

    public static void main (String[] args)

    {

        // входной массив содержит `n` чисел от 1 до `n-1`

        // с одним дубликатом, где `n` – длина массива

        int[] nums = { 1, 2, 3, 4, 2 };

        System.out.println(“The duplicate element is “ + findDuplicate(nums));

    }

}

Скачать  Выполнить код

результат:

The duplicate element is 2

Python

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

# Функция поиска повторяющегося элемента в списке с ограниченным диапазоном

def findDuplicate(nums):

    duplicate = 1

    # делаем для каждого элемента в списке

    for i in range(len(nums)):

        # получить значение текущего элемента

        val = nums[i] if (nums[i] < 0) else nums[i]

        # делает элемент с индексом val отрицательным, если он положительный

        if nums[val] >= 0:

            nums[val] = nums[val]

        else:

            #, если элемент уже отрицательный, повторяется

            duplicate = val

            break

    # восстановить исходный список перед возвратом

    for i in range(len(nums)):

        # делает отрицательные элементы положительными

        if nums[i] < 0:

            nums[i] = nums[i]

    # возвращает повторяющийся элемент

    return duplicate

if __name__ == ‘__main__’:

    # список ввода содержит `n` чисел от 1 до `n-1`

    # с одним дубликатом, где `n = len(nums)`

    nums = [1, 2, 3, 4, 2]

    print(‘The duplicate element is’, findDuplicate(nums))

Скачать  Выполнить код

результат:

The duplicate element is 2

Временная сложность приведенного выше решения равна O(n).

Подход 3: Использование исключающего ИЛИ

Мы также можем решить эту проблему, взяв xor всех элементов массива с номерами 1 в n-1. Поскольку одни и те же элементы будут компенсировать друг друга, как a^a = 0, 0^0 = 0 а также a^0 = a, у нас останется повторяющийся элемент. Этот подход демонстрируется ниже на C, Java и Python:

C

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

#include <stdio.h>

// Функция для поиска повторяющегося элемента в массиве с ограниченным диапазоном

int findDuplicate(int nums[], int n)

{

    int xor = 0;

    // берем xor всех элементов массива

    for (int i = 0; i < n; i++) {

        xor ^= nums[i];

    }

    // возьмем xor чисел от 1 до `n-1`

    for (int i = 1; i <= n1; i++) {

        xor ^= i;

    }

    // одинаковые элементы будут компенсировать друг друга, так как a ^ a = 0,

    // 0 ^ 0 = 0 и а ^ 0 = а

    // `xor` будет содержать недостающее число

    return xor;

}

int main()

{

    // входной массив содержит `n` чисел от 1 до `n-1` с одним дубликатом

    int nums[] = { 1, 2, 3, 4, 2 };

    int n = sizeof(nums) / sizeof(nums[0]);

    printf(“The duplicate element is %d”, findDuplicate(nums, n));

    return 0;

}

Скачать  Выполнить код

результат:

The duplicate element is 4

Java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

class Main

{

    // Функция для поиска повторяющегося элемента в массиве с ограниченным диапазоном

    public static int findDuplicate(int[] nums)

    {

        int xor = 0;

        // берем xor всех элементов массива

        for (int value: nums) {

            xor ^= value;

        }

        // возьмем xor чисел от 1 до `n-1`

        for (int i = 1; i <= nums.length 1; i++) {

            xor ^= i;

        }

        // одинаковые элементы будут компенсировать друг друга, так как a ^ a = 0,

        // 0 ^ 0 = 0 и а ^ 0 = а

        // `xor` будет содержать недостающее число

        return xor;

    }

    public static void main(String[] args)

    {

        // входной массив содержит `n` чисел от 1 до `n-1`

        // с одним дубликатом, где `n` – длина массива

        int[] nums = { 1, 2, 3, 4, 4 };

        System.out.println(“The duplicate element is “ + findDuplicate(nums));

    }

}

Скачать  Выполнить код

результат:

The duplicate element is 4

Python

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

# Функция поиска повторяющегося элемента в списке с ограниченным диапазоном

def findDuplicate(nums):

    xor = 0

    # взять xor всех элементов списка

    for i in range(len(nums)):

        xor ^= nums[i]

    # взять xor чисел от 1 до `n-1`

    for i in range(1, len(nums)):

        xor ^= i

    # одни и те же элементы будут отменять друг друга как ‘a ^ a = 0’,

    # 0 ^ 0 = 0 и а ^ 0 = а

    # `xor` будет содержать недостающее число

    return xor

if __name__ == ‘__main__’:

    # список ввода содержит `n` чисел от 1 до `n-1`

    # с одним дубликатом, где `n = len(nums)`

    nums = [1, 2, 3, 4, 4]

    print(‘The duplicate element is’, findDuplicate(nums))

Скачать  Выполнить код

результат:

The duplicate element is 4

Временная сложность приведенного выше решения равна O(n).

Подход 4: использование разницы в сумме

Наконец, пост будет неполным без этого хрестоматийного решения: найти сумму всех элементов и найти разницу между ними и всеми элементами, которые там должны быть. Это показано ниже на C++, Java и Python:

C++

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

#include <iostream>

#include <vector>

#include <numeric>

using namespace std;

int find_duplicate(vector<int> const &nums)

{

    int size = nums.size();

    int actual_sum = accumulate(nums.begin(), nums.end(), 0);

    int expected_sum = size * (size 1) / 2;

    return actual_sum expected_sum;

}

int main()

{

    vector<int> nums = { 1, 2, 3, 4, 4 };

    cout << “The duplicate element is “ << find_duplicate(nums);

    return 0;

}

Скачать  Выполнить код

результат:

The duplicate element is 4

Java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

import java.util.stream.IntStream;

class Main

{

    public static int findDuplicate(int[] nums)

    {

        int actual_sum = IntStream.of(nums).sum();

        int expected_sum = nums.length * (nums.length 1) / 2;

        return actual_sum expected_sum;

    }

    public static void main(String[] args)

    {

        int[] nums = { 1, 2, 3, 4, 4 };

        System.out.println(“The duplicate element is “ + findDuplicate(nums));

    }

}

Скачать  Выполнить код

результат:

The duplicate element is 4

Python

def findDuplicate(nums):

    actual_sum = sum(nums)

    expected_sum = len(nums) * (len(nums) 1) // 2

    return actual_sum expected_sum

if __name__ == ‘__main__’:

    nums = [1, 2, 3, 4, 4]

    print(‘The duplicate element is’, findDuplicate(nums))

Скачать  Выполнить код

результат:

The duplicate element is 4

Временная сложность приведенного выше решения равна O(n).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;
 
template<typename T>
struct RepeatedList
{
vector<T> source;
map< T, vector<size_t> > repeatitions;
 
RepeatedList(T *arr, size_t n)
{
vector<T> tmp_vec(arr, arr+n);
source=tmp_vec;
find_all_repeated();
}
 
void find_all_repeated()
{
size_t len = source.size();
 
for(size_t i=0; i<len; ++i)
{
 
for(size_t j=0; j<len; ++j)
{
if(source[i]==source[j])
{
map< T, vector<size_t> >:: iterator fnd;
    fnd=repeatitions.find(source[i]);   
    if(fnd != repeatitions.end() && find(fnd->second.begin(), fnd->second.end(), j)==fnd->second.end())
    {
fnd->second.push_back(j);
    }
    else
    {
vector<size_t> vadd;
vadd.push_back(i);
pair< T, vector<size_t> > toAdd(source[i],vadd);
repeatitions.insert(toAdd);
    }
}
}
}
}
void show_all_repeated()
{
size_t slen = source.size();
cout<<"nnThe source sequense from "<<slen<<" items was:n";
for(size_t i=0; i<slen; ++i)
cout<<source[i]<<" ";
cout<<"n_________________________n";
size_t len = repeatitions.size();
map< T, vector<size_t> >:: iterator it=repeatitions.begin(), it_end=repeatitions.end();
bool norep=true;
for(; it!=it_end; ++it)
{
size_t reps=it->second.size();
if(reps>1)
{
norep=false;
    cout<<"nnThe value "<<it->first<<" has been found "<<reps<<" timesnand it has happened at positions:n";
size_t vlen = it->second.size();
    for(size_t i=0; i<vlen; ++i)cout<< it->second[i]+1<<" ";
}
}
if(norep)cout<<"nNo repeatitions has been found and all values are unique.";
cout<<endl;
}
};
 
int main(int argc, char* argv[])
{
short ar[]={1,2,3,4,5,98,34};
RepeatedList<short> rep_list1(ar, sizeof(ar)/sizeof(ar[0]));
rep_list1.show_all_repeated();
 
int arr[]={1,2,1,3,4,5,1,1,2,34,43,2,33,34,78,2,1,3,4,5,6,98,34,1};
RepeatedList<int> rep_list2(arr, sizeof(arr)/sizeof(arr[0]));
rep_list2.show_all_repeated();
cout<<endl;
system("pause");
return 0;
}

Добавить комментарий