📌  相关文章
📜  使用O(n)时间并通过使用O(1)多余空间在数组中复制|套装3

📅  最后修改于: 2021-04-23 20:29:16             🧑  作者: Mango

给定n个元素组成的数组,其中包含从0到n-1的元素,这些数字中的任何一个都会出现任意次。在O(n)中查找这些重复的数字,并且仅使用恒定的存储空间。需要保持元素重复的顺序。如果不存在重复元素,则打印-1。
例子:

Input : arr[] = {1, 2, 3, 1, 3, 6, 6}
Output : 1, 3, 6
Elements 1, 3 and 6 are repeating.
Second occurrence of 1 is found
first followed by repeated occurrence
of 3 and 6.

Input : arr[] = {0, 3, 1, 3, 0}
Output : 3, 0
Second occurrence of 3 is found
first followed by second occurrence 
of 0.
推荐:在继续解决方案之前,请先在“实践”上解决它。

我们在以下帖子中讨论了针对此问题的两种方法:
查找O(n)时间和O(1)多余空间中的重复项|套装1
使用O(n)时间并通过使用O(1)多余空间在数组中复制|套装2
第一种方法存在问题。它多次打印重复的数字。例如:{1、6、3、1、3、6、6},其输出将为:3 6 6.在第二种方法中,尽管每个重复的项目仅打印一次,但不会保持其重复发生的顺序。为了按元素重复的顺序打印元素,对第二种方法进行了修改。为了标记数组的元素大小的存在,将n添加到与数组元素arr [i]相对应的索引位置arr [i]。在添加n之前,请检查索引arr [i]上的值是否大于或等于n。如果大于或等于,则表示元素arr [i]正在重复。为避免多次打印重复元素,请检查它是否是arr [i]的第一次重复。如果索引位置arr [i]的值小于2 * n,则是第一次重复。这是因为,如果元素arr [i]在此之前仅发生过一次,则n仅被添加到索引arr [i]一次,因此索引arr [i]的值小于2 * n。将n添加到索引arr [i],以使值变得大于或等于2 * n,这将防止进一步打印当前的重复元素。同样,如果索引arr [i]的值小于n,则它是元素arr [i]的首次出现(不是重复)。因此,要标记此元素,请在索引arr [i]处将n添加到元素。
下面是上述方法的实现:

C++
// C++ program to print all elements that
// appear more than once.
#include 
using namespace std;
 
// Function to find repeating elements
void printDuplicates(int arr[], int n)
{
    int i;
 
    // Flag variable used to
    // represent whether repeating
    // element is found or not.
    int fl = 0;
 
    for (i = 0; i < n; i++) {
 
        // Check if current element is
        // repeating or not. If it is
        // repeating then value will
        // be greater than or equal to n.
        if (arr[arr[i] % n] >= n) {
 
            // Check if it is first
            // repetition or not. If it is
            // first repetition then value
            // at index arr[i] is less than
            // 2*n. Print arr[i] if it is
            // first repetition.
            if (arr[arr[i] % n] < 2 * n) {
                cout << arr[i] % n << " ";
                fl = 1;
            }
        }
 
        // Add n to index arr[i] to mark
        // presence of arr[i] or to
        // mark repetition of arr[i].
        arr[arr[i] % n] += n;
    }
 
    // If flag variable is not set
    // then no repeating element is
    // found. So print -1.
    if (!fl)
        cout << "-1";
}
 
// Driver Function
int main()
{
    int arr[] = { 1, 6, 3, 1, 3, 6, 6 };
    int arr_size = sizeof(arr) / sizeof(arr[0]);
    printDuplicates(arr, arr_size);
    return 0;
}


Java
// Java program to print all elements
// that appear more than once.
import java.io.*;
 
class GFG
{
     
// Function to find repeating elements
static void printDuplicates(int arr[], int n)
{
    int i;
 
    // Flag variable used to
    // represent whether repeating
    // element is found or not.
    int fl = 0;
 
    for (i = 0; i < n; i++)
    {
 
        // Check if current element is
        // repeating or not. If it is
        // repeating then value will
        // be greater than or equal to n.
        if (arr[arr[i] % n] >= n)
        {
 
            // Check if it is first
            // repetition or not. If it is
            // first repetition then value
            // at index arr[i] is less than
            // 2*n. Print arr[i] if it is
            // first repetition.
            if (arr[arr[i] % n] < 2 * n)
            {
                System.out.print( arr[i] % n + " ");
                fl = 1;
            }
        }
 
        // Add n to index arr[i] to mark
        // presence of arr[i] or to
        // mark repetition of arr[i].
        arr[arr[i] % n] += n;
    }
 
    // If flag variable is not set
    // then no repeating element is
    // found. So print -1.
    if (!(fl > 0))
        System.out.println("-1");
}
 
// Driver Code
public static void main (String[] args)
{
    int arr[] = { 1, 6, 3, 1, 3, 6, 6 };
    int arr_size = arr.length;
    printDuplicates(arr, arr_size);
}
}
 
// This code is contributed by anuj_67.


Python 3
# Python 3 program to print all elements that
# appear more than once.
 
# Function to find repeating elements
def printDuplicates(arr, n):
 
    # Flag variable used to
    # represent whether repeating
    # element is found or not.
    fl = 0;
 
    for i in range (0, n):
 
        # Check if current element is
        # repeating or not. If it is
        # repeating then value will
        # be greater than or equal to n.
        if (arr[arr[i] % n] >= n):
 
            # Check if it is first
            # repetition or not. If it is
            # first repetition then value
            # at index arr[i] is less than
            # 2*n. Print arr[i] if it is
            # first repetition.
            if (arr[arr[i] % n] < 2 * n):
                print(arr[i] % n, end = " ")
                fl = 1;
 
        # Add n to index arr[i] to mark
        # presence of arr[i] or to
        # mark repetition of arr[i].
        arr[arr[i] % n] += n;
 
    # If flag variable is not set
    # then no repeating element is
    # found. So print -1.
    if (fl == 0):
        print("-1")
 
# Driver Function
arr = [ 1, 6, 3, 1, 3, 6, 6 ];
arr_size = len(arr);
printDuplicates(arr, arr_size);
 
# This code is contributed
# by Akanksha Rai


C#
// C# program to print all elements
// that appear more than once.
using System;
 
class GFG
{
 
// Function to find repeating elements
static void printDuplicates(int []arr, int n)
{
    int i;
 
    // Flag variable used to
    // represent whether repeating
    // element is found or not.
    int fl = 0;
 
    for (i = 0; i < n; i++)
    {
 
        // Check if current element is
        // repeating or not. If it is
        // repeating then value will
        // be greater than or equal to n.
        if (arr[arr[i] % n] >= n)
        {
 
            // Check if it is first
            // repetition or not. If it is
            // first repetition then value
            // at index arr[i] is less than
            // 2*n. Print arr[i] if it is
            // first repetition.
            if (arr[arr[i] % n] < 2 * n)
            {
                Console.Write( arr[i] % n + " ");
                fl = 1;
            }
        }
 
        // Add n to index arr[i] to mark
        // presence of arr[i] or to
        // mark repetition of arr[i].
        arr[arr[i] % n] += n;
    }
 
    // If flag variable is not set
    // then no repeating element is
    // found. So print -1.
    if (!(fl > 0))
        Console.Write("-1");
}
 
// Driver Code
public static void Main ()
{
    int []arr = { 1, 6, 3, 1, 3, 6, 6 };
    int arr_size = arr.Length;
    printDuplicates(arr, arr_size);
}
}
 
// This code is contributed
// by 29AjayKumar


PHP
= $n)
        {
 
            // Check if it is first
            // repetition or not. If it is
            // first repetition then value
            // at index arr[i] is less than
            // 2*n. Print arr[i] if it is
            // first repetition.
            if ($arr[$arr[$i] % $n] < 2 * $n)
            {
                echo $arr[$i] % $n . " ";
                $fl = 1;
            }
        }
 
        // Add n to index arr[i] to mark
        // presence of arr[i] or to
        // mark repetition of arr[i].
        $arr[$arr[$i] % $n] += $n;
    }
 
    // If flag variable is not set
    // then no repeating element is
    // found. So print -1.
    if (!$fl)
        echo "-1";
}
 
// Driver Function
$arr = array(1, 6, 3, 1, 3, 6, 6);
$arr_size = sizeof($arr);
printDuplicates($arr, $arr_size);
 
// This code is contributed
// by Mukul Singh


Javascript


输出:
1 3 6

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