📌  相关文章
📜  查找在数组中出现一次的元素,其中每个其他元素出现两次

📅  最后修改于: 2022-05-13 01:57:52.936000             🧑  作者: Mango

查找在数组中出现一次的元素,其中每个其他元素出现两次

给定一个整数数组。除了一个出现一次的数字外,所有数字都出现两次。在 O(n) 时间和恒定的额外空间中找到数字。

例子 :

Input:  ar[] = {7, 3, 5, 4, 5, 3, 4}
Output: 7 

一种解决方案是检查每个元素是否出现一次。一旦找到具有单次出现的元素,将其返回。该解决方案的时间复杂度为 O(n 2 )。

更好的解决方案是使用散列。
1)遍历所有元素并将它们放入哈希表中。元素用作键,出现次数用作哈希表中的值。
2)再次遍历数组,打印哈希表中count为1的元素。
此解决方案在 O(n) 时间内有效,但需要额外空间。
最好的解决方案是使用 XOR。所有数组元素的 XOR 为我们提供了一次出现的数字。这个想法是基于以下两个事实。
a) 一个数与自身的 XOR 为 0。
b) 数字与 0 的异或是数字本身。

Let us consider the above example.  
Let ^ be xor operator as in C and C++.

res = 7 ^ 3 ^ 5 ^ 4 ^ 5 ^ 3 ^ 4

Since XOR is associative and commutative, above 
expression can be written as:
res = 7 ^ (3 ^ 3) ^ (4 ^ 4) ^ (5 ^ 5)  
    = 7 ^ 0 ^ 0 ^ 0
    = 7 ^ 0
    = 7 

以下是上述算法的实现。

C++
// C++ program to find the array
// element that appears only once
#include 
using namespace std;
 
int findSingle(int ar[], int ar_size)
    {
        // Do XOR of all elements and return
        int res = ar[0];
        for (int i = 1; i < ar_size; i++)
            res = res ^ ar[i];
 
        return res;
    }
 
// Driver code
int main()
    {
        int ar[] = {2, 3, 5, 4, 5, 3, 4};
        int n = sizeof(ar) / sizeof(ar[0]);
        cout << "Element occurring once is "
             << findSingle(ar, n);
        return 0;
    }


Java
// Java program to find the array
// element that appears only once
class MaxSum
{
    // Return the maximum Sum of difference
    // between consecutive elements.
    static int findSingle(int ar[], int ar_size)
    {
        // Do XOR of all elements and return
        int res = ar[0];
        for (int i = 1; i < ar_size; i++)
            res = res ^ ar[i];
     
        return res;
    }
 
    // Driver code
    public static void main (String[] args)
    {
        int ar[] = {2, 3, 5, 4, 5, 3, 4};
        int n = ar.length;
        System.out.println("Element occurring once is " +
                            findSingle(ar, n) + " ");
    }
}
// This code is contributed by Prakriti Gupta


Python3
# function to find the once
# appearing element in array
def findSingle( ar, n):
     
    res = ar[0]
     
    # Do XOR of all elements and return
    for i in range(1,n):
        res = res ^ ar[i]
     
    return res
 
# Driver code
ar = [2, 3, 5, 4, 5, 3, 4]
print "Element occurring once is", findSingle(ar, len(ar))
 
# This code is contributed by __Devesh Agrawal__


C#
// C# program to find the array
// element that appears only once
using System;
 
class GFG
{
    // Return the maximum Sum of difference
    // between consecutive elements.
    static int findSingle(int []ar, int ar_size)
    {
        // Do XOR of all elements and return
        int res = ar[0];
        for (int i = 1; i < ar_size; i++)
            res = res ^ ar[i];
     
        return res;
    }
 
    // Driver code
    public static void Main ()
    {
        int []ar = {2, 3, 5, 4, 5, 3, 4};
        int n = ar.Length;
        Console.Write("Element occurring once is " +
                            findSingle(ar, n) + " ");
    }
}
 
// This code is contributed by nitin mittal.


PHP


Javascript


C++
// C++ program to find
// element that appears once
#include 
 
using namespace std;
 
// function which find number
int singleNumber(int nums[],int n)
{
    map m;
    long sum1 = 0,sum2 = 0;
 
    for(int i = 0; i < n; i++)
    {
        if(m[nums[i]] == 0)
        {
            sum1 += nums[i];
            m[nums[i]]++;
        }
        sum2 += nums[i];
    }
     
    // applying the formula.
    return 2 * (sum1) - sum2;
}
 
// Driver code
int main()
{
    int a[] = {2, 3, 5, 4, 5, 3, 4};
    int n = 7;
    cout << singleNumber(a,n) << "\n";
 
    int b[] = {15, 18, 16, 18, 16, 15, 89};
 
    cout << singleNumber(b,n);
    return 0;
}
 
// This code is contributed by mohit kumar 29


Java
// Java program to find
// element that appears once
import java.io.*;
import java.util.*;
 
class GFG
{
 
    // function which find number
    static int singleNumber(int[] nums, int n)
    {
        HashMap m = new HashMap<>();
        long sum1 = 0, sum2 = 0;
        for (int i = 0; i < n; i++)
        {
            if (!m.containsKey(nums[i]))
            {
                sum1 += nums[i];
                m.put(nums[i], 1);
            }
            sum2 += nums[i];
        }
 
        // applying the formula.
        return (int)(2 * (sum1) - sum2);
    }
 
    // Driver code
    public static void main(String args[])
    {
        int[] a = {2, 3, 5, 4, 5, 3, 4};
        int n = 7;
        System.out.println(singleNumber(a,n));
 
        int[] b = {15, 18, 16, 18, 16, 15, 89};
        System.out.println(singleNumber(b,n));
    }
}
 
// This code is contributed by rachana soma


Python3
# Python3 program to find
# element that appears once
 
# function which find number
def singleNumber(nums):
 
# applying the formula.
    return 2 * sum(set(nums)) - sum(nums)
 
# driver code
a = [2, 3, 5, 4, 5, 3, 4]
print (int(singleNumber(a)))
 
a = [15, 18, 16, 18, 16, 15, 89]
print (int(singleNumber(a)))
 
# This code is contributed by "Abhishek Sharma 44"


C#
// C# program to find
// element that appears once
using System;
using System.Collections.Generic;
 
class GFG
{
 
    // function which find number
    static int singleNumber(int[] nums, int n)
    {
        Dictionary m = new Dictionary();
        long sum1 = 0, sum2 = 0;
        for (int i = 0; i < n; i++)
        {
            if (!m.ContainsKey(nums[i]))
            {
                sum1 += nums[i];
                m.Add(nums[i], 1);
            }
            sum2 += nums[i];
        }
 
        // applying the formula.
        return (int)(2 * (sum1) - sum2);
    }
 
    // Driver code
    public static void Main(String []args)
    {
        int[] a = {2, 3, 5, 4, 5, 3, 4};
        int n = 7;
        Console.WriteLine(singleNumber(a,n));
 
        int[] b = {15, 18, 16, 18, 16, 15, 89};
        Console.WriteLine(singleNumber(b,n));
    }
}
 
/* This code contributed by PrinciRaj1992 */


Javascript


C++
#include 
using namespace std;
int singleelement(int arr[], int n)
{
    int low = 0, high = n - 2;
    int mid;
    while (low <= high) {
        mid = (low + high) / 2;
        if (arr[mid] == arr[mid ^ 1]) {
            low = mid + 1;
        }
        else {
            high = mid - 1;
        }
    }
    return arr[low];
}
int main()
{
    int arr[] = { 2, 3, 5, 4, 5, 3, 4 };
    int size = sizeof(arr) / sizeof(arr[0]);
    sort(arr, arr + size);
    cout << singleelement(arr, size);
    return 0;
}
 
// This code is contributed by Sohom Das


Java
import java.io.*;
import java.util.Arrays;
 
class GFG{
     
static int singleelement(int arr[], int n)
{
    int low = 0, high = n - 2;
    int mid;
     
    while (low <= high)
    {
        mid = (low + high) / 2;
        if (arr[mid] == arr[mid ^ 1])
        {
            low = mid + 1;
        }
        else
        {
            high = mid - 1;
        }
    }
    return arr[low];
}
 
// Driver code
public static void main(String[] args)
{
    int arr[] = { 2, 3, 5, 4, 5, 3, 4 };
    int size = 7;
    Arrays.sort(arr);
     
    System.out.println(singleelement(arr, size));
}
}
 
// This code is contributed by dassohom5


Python3
def singleelement(arr, n):
    low = 0
    high = n - 2
    mid = 0
    while (low <= high):
        mid = (low + high) // 2
        if (arr[mid] == arr[mid ^ 1]):
            low = mid + 1
        else:
            high = mid - 1
     
    return arr[low]
     
# Driver code
arr = [2, 3, 5, 4, 5, 3, 4]
size = len(arr)
arr.sort()
print(singleelement(arr, size))
 
# This code is contributed by shivanisingh


C#
using System;
using System.Collections;
 
class GFG{
     
static int singleelement(int[] arr, int n)
{
    int low = 0, high = n - 2;
    int mid;
     
    while (low <= high)
    {
        mid = (low + high) / 2;
         
        if (arr[mid] == arr[mid ^ 1])
        {
            low = mid + 1;
        }
        else
        {
            high = mid - 1;
        }
    }
    return arr[low];
}
 
// Driver code
public static void Main()
{
    int[] arr = { 2, 3, 5, 4, 5, 3, 4 };
    int size = 7;
    Array.Sort(arr);
     
    Console.WriteLine(singleelement(arr, size));
}
}
 
// This code is contributed by dassohom5


Javascript


输出:

Element occurring once is 2

该解决方案的时间复杂度为 O(n),需要 O(1) 额外空间。

另一种方法:
这不是一种有效的方法,而只是获得所需结果的另一种方法。如果我们将每个数字相加一次并将总和乘以 2,我们将得到数组中每个元素总和的两倍。然后,我们将从 two_sum 中减去整个数组的总和,得到所需的数字(在数组中出现一次)。
数组 [] : [a, a, b, b, c, c, d]
数学方程式 = 2*(a+b+c+d) – (a + a + b + b + c + c + d)

用更简单的话来说: 2*(sum_of_array_without_duplicates) – (sum_of_array)

let arr[] = {7, 3, 5, 4, 5, 3, 4}
Required no = 2*(sum_of_array_without_duplicates) - (sum_of_array)
            = 2*(7 + 3 + 5 + 4) - (7 + 3 + 5 + 4 + 5 + 3 + 4) 
            = 2*     19         -      31 
            = 38 - 31
            = 7 (required answer)

正如我们所知,集合不包含任何重复的元素,我们将在这里使用集合

以下是上述方法的实现:

C++

// C++ program to find
// element that appears once
#include 
 
using namespace std;
 
// function which find number
int singleNumber(int nums[],int n)
{
    map m;
    long sum1 = 0,sum2 = 0;
 
    for(int i = 0; i < n; i++)
    {
        if(m[nums[i]] == 0)
        {
            sum1 += nums[i];
            m[nums[i]]++;
        }
        sum2 += nums[i];
    }
     
    // applying the formula.
    return 2 * (sum1) - sum2;
}
 
// Driver code
int main()
{
    int a[] = {2, 3, 5, 4, 5, 3, 4};
    int n = 7;
    cout << singleNumber(a,n) << "\n";
 
    int b[] = {15, 18, 16, 18, 16, 15, 89};
 
    cout << singleNumber(b,n);
    return 0;
}
 
// This code is contributed by mohit kumar 29

Java

// Java program to find
// element that appears once
import java.io.*;
import java.util.*;
 
class GFG
{
 
    // function which find number
    static int singleNumber(int[] nums, int n)
    {
        HashMap m = new HashMap<>();
        long sum1 = 0, sum2 = 0;
        for (int i = 0; i < n; i++)
        {
            if (!m.containsKey(nums[i]))
            {
                sum1 += nums[i];
                m.put(nums[i], 1);
            }
            sum2 += nums[i];
        }
 
        // applying the formula.
        return (int)(2 * (sum1) - sum2);
    }
 
    // Driver code
    public static void main(String args[])
    {
        int[] a = {2, 3, 5, 4, 5, 3, 4};
        int n = 7;
        System.out.println(singleNumber(a,n));
 
        int[] b = {15, 18, 16, 18, 16, 15, 89};
        System.out.println(singleNumber(b,n));
    }
}
 
// This code is contributed by rachana soma

Python3

# Python3 program to find
# element that appears once
 
# function which find number
def singleNumber(nums):
 
# applying the formula.
    return 2 * sum(set(nums)) - sum(nums)
 
# driver code
a = [2, 3, 5, 4, 5, 3, 4]
print (int(singleNumber(a)))
 
a = [15, 18, 16, 18, 16, 15, 89]
print (int(singleNumber(a)))
 
# This code is contributed by "Abhishek Sharma 44"

C#

// C# program to find
// element that appears once
using System;
using System.Collections.Generic;
 
class GFG
{
 
    // function which find number
    static int singleNumber(int[] nums, int n)
    {
        Dictionary m = new Dictionary();
        long sum1 = 0, sum2 = 0;
        for (int i = 0; i < n; i++)
        {
            if (!m.ContainsKey(nums[i]))
            {
                sum1 += nums[i];
                m.Add(nums[i], 1);
            }
            sum2 += nums[i];
        }
 
        // applying the formula.
        return (int)(2 * (sum1) - sum2);
    }
 
    // Driver code
    public static void Main(String []args)
    {
        int[] a = {2, 3, 5, 4, 5, 3, 4};
        int n = 7;
        Console.WriteLine(singleNumber(a,n));
 
        int[] b = {15, 18, 16, 18, 16, 15, 89};
        Console.WriteLine(singleNumber(b,n));
    }
}
 
/* This code contributed by PrinciRaj1992 */

Javascript


输出:

2
89

另一种方法:

这是在重复元素列表中查找单个元素的有效方法。在这种方法中,我们使用二进制搜索算法在重复元素列表中查找单个元素。在此之前,我们需要确定数组是否已排序。第一步是对数组进行排序,因为如果数组未排序,二进制搜索算法将不起作用。

现在让我们转到二分搜索实现:

数组中存在的唯一单个元素创建了两半,它们是左半部分和右半部分。现在,如果左半部分存在重复元素,则左半部分重复元素的第一个实例是偶数索引,第二个实例是奇数索引。左半部分的反面发生在右半部分(第一个实例是奇数索引,第二个实例是偶数索引)。现在应用二进制搜索算法:

1)解决方案是采用数组的两个索引(低和高),其中低点指向数组索引0,点指向数组索引(数组大小-2)。我们从 (low+high)/2 的值中取出中间指数。

2)现在检查中间索引值是落在左半边还是右半边。如果它落在左半部分,那么我们将低值更改为 mid+1,如果它落在右半部分,那么我们将高索引更改为 mid-1。为了检查它,我们使用了一个逻辑( if(arr[mid]==arr[mid^1] )。如果 mid 是偶数,那么 mid^1 将是下一个奇数索引,如果满足条件,则我们可以说我们在左索引,否则我们可以说我们在右半部分。但是如果 mid 是奇数索引,则 mid^1 将我们带到 mid-1 即前一个偶数索引,即获取相等意味着我们在右半边,否则在左半边。

3) 这样做是因为此实现的目的是在重复列表中找到单个元素。只有当低值大于高值时才有可能,因为此时低值将指向包含数组中单个元素的索引。

4)循环结束后,我们返回低索引的值。

C++

#include 
using namespace std;
int singleelement(int arr[], int n)
{
    int low = 0, high = n - 2;
    int mid;
    while (low <= high) {
        mid = (low + high) / 2;
        if (arr[mid] == arr[mid ^ 1]) {
            low = mid + 1;
        }
        else {
            high = mid - 1;
        }
    }
    return arr[low];
}
int main()
{
    int arr[] = { 2, 3, 5, 4, 5, 3, 4 };
    int size = sizeof(arr) / sizeof(arr[0]);
    sort(arr, arr + size);
    cout << singleelement(arr, size);
    return 0;
}
 
// This code is contributed by Sohom Das

Java

import java.io.*;
import java.util.Arrays;
 
class GFG{
     
static int singleelement(int arr[], int n)
{
    int low = 0, high = n - 2;
    int mid;
     
    while (low <= high)
    {
        mid = (low + high) / 2;
        if (arr[mid] == arr[mid ^ 1])
        {
            low = mid + 1;
        }
        else
        {
            high = mid - 1;
        }
    }
    return arr[low];
}
 
// Driver code
public static void main(String[] args)
{
    int arr[] = { 2, 3, 5, 4, 5, 3, 4 };
    int size = 7;
    Arrays.sort(arr);
     
    System.out.println(singleelement(arr, size));
}
}
 
// This code is contributed by dassohom5

Python3

def singleelement(arr, n):
    low = 0
    high = n - 2
    mid = 0
    while (low <= high):
        mid = (low + high) // 2
        if (arr[mid] == arr[mid ^ 1]):
            low = mid + 1
        else:
            high = mid - 1
     
    return arr[low]
     
# Driver code
arr = [2, 3, 5, 4, 5, 3, 4]
size = len(arr)
arr.sort()
print(singleelement(arr, size))
 
# This code is contributed by shivanisingh

C#

using System;
using System.Collections;
 
class GFG{
     
static int singleelement(int[] arr, int n)
{
    int low = 0, high = n - 2;
    int mid;
     
    while (low <= high)
    {
        mid = (low + high) / 2;
         
        if (arr[mid] == arr[mid ^ 1])
        {
            low = mid + 1;
        }
        else
        {
            high = mid - 1;
        }
    }
    return arr[low];
}
 
// Driver code
public static void Main()
{
    int[] arr = { 2, 3, 5, 4, 5, 3, 4 };
    int size = 7;
    Array.Sort(arr);
     
    Console.WriteLine(singleelement(arr, size));
}
}
 
// This code is contributed by dassohom5

Javascript


输出:

2

解的时间复杂度为O(N log(N))+O(log N),空间复杂度为O(1)。