给定一个数组,其中除一个元素外,所有元素均出现偶数次。所有重复出现的元素均成对出现,并且这些对不相邻(任何元素不能连续出现两次以上)。查找出现奇数次的元素。
请注意,像{2,2,1,2,2,1,1,1}这样的输入是有效的,因为所有重复出现都是成对发生的,并且这些对不相邻。像{2,1,2}这样的输入无效,因为重复元素不会成对出现。同样,由于{2,2,2,2,2}之类的输入是无效的,因为两对2相邻。像{2,2,2,1}这样的输入也是无效的,因为连续出现了3个2。
例子 :
Input: arr[] = {1, 1, 2, 2, 1, 1, 2, 2, 13, 1, 1, 40, 40, 13, 13}
Output: 13
Input: arr[] = {1, 1, 2, 2, 3, 3, 4, 4, 3, 600, 600, 4, 4}
Output: 3
强烈建议您最小化浏览器,然后自己尝试。
一个简单的解决方案是对数组进行排序,然后从左到右遍历该数组。由于数组已排序,因此我们可以轻松找出所需的元素。该解决方案的时间复杂度为O(n Log n)
更好的解决方案是对所有元素进行XOR,XOR结果将给出出现的奇数元素。该解决方案的时间复杂度为O(n)。有关更多详细信息,请参见基于XOR的解决方案以添加终止。
一个有效的解决方案可以在O(Log n)时间中找到所需的元素。这个想法是使用二进制搜索。下面是对输入数组的观察。
由于该元素出现奇数次,因此该元素必须存在一次。例如,在{2,1,1,2,2)中,前2个为奇数出现。因此,想法是使用二进制搜索找到这种奇怪的情况。
奇数出现之前的所有元素的第一个出现在偶数索引(0,2,..),下一个出现在奇数索引(1,3,…)。并且所有元素在奇数索引处先出现后在偶数索引处后发生。
1)找到中间索引,说’mid’。
2)如果“ mid”是偶数,则比较arr [mid]和arr [mid + 1]。如果两者相同,则在“ mid”之后出现元素的奇数,否则在mid之前出现。
3)如果’mid’为奇数,则比较arr [mid]和arr [mid – 1]。如果两者相同,则在“ mid”之后出现一个奇数出现,否则在mid之前出现。
下面是基于以上思想的实现。
C++
// C program to find the element that appears odd number of time
#include
// A Binary Search based function to find the element
// that appears odd times
void search(int *arr, int low, int high)
{
// Base cases
if (low > high)
return;
if (low==high)
{
printf("The required element is %d ", arr[low]);
return;
}
// Find the middle point
int mid = (low+high)/2;
// If mid is even and element next to mid is
// same as mid, then output element lies on
// right side, else on left side
if (mid%2 == 0)
{
if (arr[mid] == arr[mid+1])
search(arr, mid+2, high);
else
search(arr, low, mid);
}
else // If mid is odd
{
if (arr[mid] == arr[mid-1])
search(arr, mid+1, high);
else
search(arr, low, mid-1);
}
}
// Driver program
int main()
{
int arr[] = {1, 1, 2, 2, 1, 1, 2, 2, 13, 1, 1, 40, 40};
int len = sizeof(arr)/sizeof(arr[0]);
search(arr, 0, len-1);
return 0;
}
Java
// Java program to find the element
// that appears odd number of time
class GFG
{
// A Binary Search based function to find
// the element that appears odd times
static void search(int arr[], int low, int high)
{
// Base cases
if (low > high)
return;
if (low == high)
{
System.out.printf("The required element is %d "
, arr[low]);
return;
}
// Find the middle point
int mid = (low + high)/2;
// If mid is even and element next to mid is
// same as mid, then output element lies on
// right side, else on left side
if (mid % 2 == 0)
{
if (arr[mid] == arr[mid + 1])
search(arr, mid + 2, high);
else
search(arr, low, mid);
}
// If mid is odd
else
{
if (arr[mid] == arr[mid - 1])
search(arr, mid + 1, high);
else
search(arr, low, mid - 1);
}
}
// Driver program
public static void main(String[] args)
{
int arr[] = {1, 1, 2, 2, 1, 1, 2, 2, 13,
1, 1, 40, 40};
int len = arr.length;
search(arr, 0, len-1);
}
}
// This code is contributed by
// Smitha DInesh Semwal
Python
# Python program to find the element that appears odd number of times
# O(log n) approach
# Binary search based function
# Returns the element that appears odd number of times
def search(arr, low, high):
# Base case
if low > high:
return None
if low == high:
return arr[low]
# Find the middle point
mid = (low + high)/2;
# If mid is even
if mid%2 == 0:
# If the element next to mid is same as mid,
# then output element lies on right side,
# else on left side
if arr[mid] == arr[mid+1]:
return search(arr, mid+2, high)
else:
return search(arr, low, mid)
else:
# else if mid is odd
if arr[mid] == arr[mid-1]:
return search(arr, mid+1, high)
else:
# (mid-1) because target element can only exist at even place
return search(arr, low, mid-1)
# Test array
arr = [ 1, 1, 2, 2, 1, 1, 2, 2, 13, 1, 1, 40, 40 ]
result = search(arr, 0, len(arr)-1 )
if result is not None:
print "The required element is %d " % result
else:
print "Invalid array"
C#
// C# program to find the element
// that appears odd number of time
using System;
class GFG {
// A Binary Search based function to find
// the element that appears odd times
static void search(int []arr, int low, int high)
{
// Base cases
if (low > high)
return;
if (low == high)
{
Console.WriteLine("The required element is "+
arr[low]);
return;
}
// Find the middle point
int mid = (low + high)/2;
// If mid is even and element next to mid is
// same as mid, then output element lies on
// right side, else on left side
if (mid % 2 == 0)
{
if (arr[mid] == arr[mid + 1])
search(arr, mid + 2, high);
else
search(arr, low, mid);
}
// If mid is odd
else
{
if (arr[mid] == arr[mid - 1])
search(arr, mid + 1, high);
else
search(arr, low, mid - 1);
}
}
// Driver program
public static void Main()
{
int []arr = {1, 1, 2, 2, 1, 1, 2, 2, 13,
1, 1, 40, 40};
int len = arr.Length;
search(arr, 0, len-1);
}
}
// This code is contributed by Sam007
PHP
$high)
return;
if ($low == $high)
{
echo "The required element is ",
$arr[$low];
return;
}
// Find the middle point
$mid = ($low + $high) / 2;
// If mid is even and element
// next to mid is same as mid,
// then output element lies on
// right side, else on left side
if ($mid % 2 == 0)
{
if ($arr[$mid] == $arr[$mid + 1])
search($arr, $mid + 2, $high);
else
search($arr, $low, $mid);
}
// If mid is odd
else
{
if ($arr[$mid] == $arr[$mid - 1])
search($arr, $mid + 1, $high);
else
search($arr, $low, $mid - 1);
}
}
// Driver Code
$arr = array(1, 1, 2, 2, 1, 1, 2,
2, 13, 1, 1, 40, 40);
$len = count($arr);;
search($arr, 0, $len - 1);
// This code is contributed by anuj_67.
?>
Javascript
输出 :
The required element is 13
时间复杂度: O(Log n)