非常大的排序数组中唯一元素的计数
给定一个大小为N的排序数组arr[] ,任务是找出该数组中唯一元素的数量。
注意:数组非常大,唯一编号明显更少。即,(唯一元素<<数组的大小)。
例子:
Input: arr[] = {1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 5, 5, 7, 7, 8, 8, 9, 9, 10, 11, 12}
Output: 10
Explanation: 10 unique elements are: 1, 2, 3, 5, 7, 8, 9, 10, 11, 12
Input: arr[] = {1, 1, 1, 2, 2, 2, 2, 3, 3, 4, 4, 5, 5, 5, 5, 9, 9, 9, 10, 10, 10}
Output: 7
Explanation: 7 unique elements are: 1, 2, 3, 4, 5, 9, 10
朴素方法:当给定数组已排序时,一种简单的方法是遍历整个元素并将它们与之前的元素进行比较。如果不同,则计算该元素。
时间复杂度: 在)
辅助空间: O(1)。
基于二分搜索的方法:想法是使用二分搜索 因为数组是排序的。请按照以下步骤操作:
- 取第一个数字,然后使用二进制搜索找到它的最后一次出现或上限。
- 然后将其视为一个独特的元素。
- 将指针指向下一个不同的元素并重复相同的步骤。
注意:此算法仅在唯一元素非常少时有效。
下面是上述方法的实现。
C++
// C++ code to implement above approach
#include
using namespace std;
// Binary search to find the last occurrence
int nextIndex(int arr[], int N, int l,
int target)
{
int result = -1;
int r = N - 1;
while (l <= r) {
int mid = l + (r - l) / 2;
if (arr[mid] == target) {
result = mid;
l = mid + 1;
}
else if (arr[mid] > target)
r = mid - 1;
else
l = mid + 1;
}
// Result will give the last occurrence &
// adding one will return next element
return result + 1;
}
// Function to find the number
// of unique elements
int unique(int arr[], int N)
{
int i = 0;
int count = 0;
while (i < N) {
// Returns the next element
i = nextIndex(arr, N, i, arr[i]);
count++;
}
return count;
}
// Driver Code
int main()
{
int arr[] = { 1, 1, 1, 1, 1, 1, 2, 2, 2,
2, 3, 5, 5, 7, 7, 8, 8, 9,
9, 10, 11, 12 };
int N = sizeof(arr) / sizeof(arr[0]);
cout << unique(arr, N);
return 0;
}
Java
// Java code to implement above approach
class GFG {
// Binary search to find the last occurrence
static int nextIndex(int arr[], int N, int l, int target) {
int result = -1;
int r = N - 1;
while (l <= r) {
int mid = l + (r - l) / 2;
if (arr[mid] == target) {
result = mid;
l = mid + 1;
} else if (arr[mid] > target)
r = mid - 1;
else
l = mid + 1;
}
// Result will give the last occurrence &
// adding one will return next element
return result + 1;
}
// Function to find the number
// of unique elements
static int unique(int arr[], int N) {
int i = 0;
int count = 0;
while (i < N) {
// Returns the next element
i = nextIndex(arr, N, i, arr[i]);
count++;
}
return count;
}
// Driver Code
public static void main(String args[]) {
int arr[] = { 1, 1, 1, 1, 1, 1, 2, 2, 2,
2, 3, 5, 5, 7, 7, 8, 8, 9,
9, 10, 11, 12 };
int N = arr.length;
System.out.println(unique(arr, N));
}
}
Python3
# Python code for the above approach
# Binary search to find the last occurrence
def nextIndex(arr, N, l, target):
result = -1
r = N - 1
while (l <= r):
mid = l + (r - l) // 2
if (arr[mid] == target):
result = mid
l = mid + 1
elif (arr[mid] > target):
r = mid - 1
else:
l = mid + 1
# Result will give the last occurrence &
# adding one will return next element
return result + 1
# Function to find the number
# of unique elements
def unique(arr, N):
i = 0
count = 0
while (i < N):
# Returns the next element
i = nextIndex(arr, N, i, arr[i])
count += 1
return count
# Driver Code
arr = [1, 1, 1, 1, 1, 1, 2, 2, 2,
2, 3, 5, 5, 7, 7, 8, 8, 9,
9, 10, 11, 12]
N = len(arr)
print(unique(arr, N))
# This code is contributed by gfgking
C#
// C# program for above approach
using System;
using System.Collections.Generic;
public class GFG
{
// Binary search to find the last occurrence
static int nextIndex(int[] arr, int N, int l, int target) {
int result = -1;
int r = N - 1;
while (l <= r) {
int mid = l + (r - l) / 2;
if (arr[mid] == target) {
result = mid;
l = mid + 1;
} else if (arr[mid] > target)
r = mid - 1;
else
l = mid + 1;
}
// Result will give the last occurrence &
// adding one will return next element
return result + 1;
}
// Function to find the number
// of unique elements
static int unique(int[] arr, int N) {
int i = 0;
int count = 0;
while (i < N) {
// Returns the next element
i = nextIndex(arr, N, i, arr[i]);
count++;
}
return count;
}
// Driver Code
static public void Main (){
int[] arr = { 1, 1, 1, 1, 1, 1, 2, 2, 2,
2, 3, 5, 5, 7, 7, 8, 8, 9,
9, 10, 11, 12 };
int N = arr.Length;
Console.WriteLine(unique(arr, N));
}
}
// This code is contributed by hrithikgarg03188
Javascript
C++
// C++ code to implement the above approach
#include
using namespace std;
// Variable to store the number
// of unique elements
int cnt = 0;
// Function to find the number
// of unique elements
void UniqueElements(int arr[], int s,
int e, bool isDuplicate)
{
// Both start and end are same
if (arr[s] == arr[e]) {
// If the element is duplicate
if (isDuplicate == false) {
cnt++;
}
}
else {
int mid = s + (e - s) / 2;
UniqueElements(arr, s, mid, isDuplicate);
UniqueElements(arr, mid + 1, e,
arr[mid] == arr[mid + 1]);
}
}
// Function to count the number
// of unique elements
int unique(int arr[], int N)
{
UniqueElements(arr, 0, N - 1, 0);
return cnt;
}
// Driver Code
int main()
{
int arr[] = { 1, 1, 1, 1, 1, 1, 2, 2, 2,
2, 3, 5, 5, 7, 7, 8, 8, 9,
9, 10, 11, 12 };
int N = sizeof(arr) / sizeof(arr[0]);
cout << unique(arr, N);
return 0;
}
Java
// Java code to implement the above approach
import java.util.*;
class GFG{
// Variable to store the number
// of unique elements
static int cnt = 0;
// Function to find the number
// of unique elements
static void UniqueElements(int arr[], int s,
int e, boolean isDuplicate)
{
// Both start and end are same
if (arr[s] == arr[e]) {
// If the element is duplicate
if (isDuplicate == false) {
cnt++;
}
}
else {
int mid = s + (e - s) / 2;
UniqueElements(arr, s, mid, isDuplicate);
UniqueElements(arr, mid + 1, e,
arr[mid] == arr[mid + 1]);
}
}
// Function to count the number
// of unique elements
static int unique(int arr[], int N)
{
UniqueElements(arr, 0, N - 1, false);
return cnt;
}
// Driver Code
public static void main(String[] args)
{
int arr[] = { 1, 1, 1, 1, 1, 1, 2, 2, 2,
2, 3, 5, 5, 7, 7, 8, 8, 9,
9, 10, 11, 12 };
int N = arr.length;
System.out.print(unique(arr, N));
}
}
// This code is contributed by 29AjayKumar
Python3
# Python code to implement the above approach
# Variable to store the number
# of unique elements
cnt = 0;
# Function to find the number
# of unique elements
def UniqueElements(arr, s, e, isDuplicate):
global cnt
# Both start and end are same
if (arr[s] == arr[e]):
# If the element is duplicate
if (isDuplicate == False):
cnt += 1;
else:
mid = s + (e - s) // 2;
UniqueElements(arr, s, mid, isDuplicate);
UniqueElements(arr, mid + 1, e, arr[mid] == arr[mid + 1]);
# Function to count the number
# of unique elements
def unique(arr, N):
UniqueElements(arr, 0, N - 1, False);
return cnt;
# Driver Code
if __name__ == '__main__':
arr = [ 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 5, 5, 7, 7, 8, 8, 9, 9, 10, 11, 12 ];
N = len(arr);
print(unique(arr, N));
# This code is contributed by Rajput-Ji
C#
// C# code to implement the above approach
using System;
public class GFG{
// Variable to store the number
// of unique elements
static int cnt = 0;
// Function to find the number
// of unique elements
static void UniqueElements(int []arr, int s,
int e, bool isDuplicate)
{
// Both start and end are same
if (arr[s] == arr[e]) {
// If the element is duplicate
if (isDuplicate == false) {
cnt++;
}
}
else {
int mid = s + (e - s) / 2;
UniqueElements(arr, s, mid, isDuplicate);
UniqueElements(arr, mid + 1, e,
arr[mid] == arr[mid + 1]);
}
}
// Function to count the number
// of unique elements
static int unique(int []arr, int N)
{
UniqueElements(arr, 0, N - 1, false);
return cnt;
}
// Driver Code
public static void Main(String[] args)
{
int []arr = { 1, 1, 1, 1, 1, 1, 2, 2, 2,
2, 3, 5, 5, 7, 7, 8, 8, 9,
9, 10, 11, 12 };
int N = arr.Length;
Console.Write(unique(arr, N));
}
}
// This code is contributed by shikhasingrajput
Javascript
10
时间复杂度: K * logO(N)。其中 K = 否。的独特元素。
辅助空间: O(1)。
基于分而治之的方法:这个问题可以通过分而治之来解决。想法是:
- 由于重复元素很大,请查看此排序数组的第一个和最后一个元素。
- 如果两者相等,则表示整个数组中仅存在该元素,并将其计为一个。
- 如果它们不同,则将数组分成两半,并对每个数组重复上述步骤。
- 最终计数是唯一元素的数量。
下面是上述方法的实现:
C++
// C++ code to implement the above approach
#include
using namespace std;
// Variable to store the number
// of unique elements
int cnt = 0;
// Function to find the number
// of unique elements
void UniqueElements(int arr[], int s,
int e, bool isDuplicate)
{
// Both start and end are same
if (arr[s] == arr[e]) {
// If the element is duplicate
if (isDuplicate == false) {
cnt++;
}
}
else {
int mid = s + (e - s) / 2;
UniqueElements(arr, s, mid, isDuplicate);
UniqueElements(arr, mid + 1, e,
arr[mid] == arr[mid + 1]);
}
}
// Function to count the number
// of unique elements
int unique(int arr[], int N)
{
UniqueElements(arr, 0, N - 1, 0);
return cnt;
}
// Driver Code
int main()
{
int arr[] = { 1, 1, 1, 1, 1, 1, 2, 2, 2,
2, 3, 5, 5, 7, 7, 8, 8, 9,
9, 10, 11, 12 };
int N = sizeof(arr) / sizeof(arr[0]);
cout << unique(arr, N);
return 0;
}
Java
// Java code to implement the above approach
import java.util.*;
class GFG{
// Variable to store the number
// of unique elements
static int cnt = 0;
// Function to find the number
// of unique elements
static void UniqueElements(int arr[], int s,
int e, boolean isDuplicate)
{
// Both start and end are same
if (arr[s] == arr[e]) {
// If the element is duplicate
if (isDuplicate == false) {
cnt++;
}
}
else {
int mid = s + (e - s) / 2;
UniqueElements(arr, s, mid, isDuplicate);
UniqueElements(arr, mid + 1, e,
arr[mid] == arr[mid + 1]);
}
}
// Function to count the number
// of unique elements
static int unique(int arr[], int N)
{
UniqueElements(arr, 0, N - 1, false);
return cnt;
}
// Driver Code
public static void main(String[] args)
{
int arr[] = { 1, 1, 1, 1, 1, 1, 2, 2, 2,
2, 3, 5, 5, 7, 7, 8, 8, 9,
9, 10, 11, 12 };
int N = arr.length;
System.out.print(unique(arr, N));
}
}
// This code is contributed by 29AjayKumar
Python3
# Python code to implement the above approach
# Variable to store the number
# of unique elements
cnt = 0;
# Function to find the number
# of unique elements
def UniqueElements(arr, s, e, isDuplicate):
global cnt
# Both start and end are same
if (arr[s] == arr[e]):
# If the element is duplicate
if (isDuplicate == False):
cnt += 1;
else:
mid = s + (e - s) // 2;
UniqueElements(arr, s, mid, isDuplicate);
UniqueElements(arr, mid + 1, e, arr[mid] == arr[mid + 1]);
# Function to count the number
# of unique elements
def unique(arr, N):
UniqueElements(arr, 0, N - 1, False);
return cnt;
# Driver Code
if __name__ == '__main__':
arr = [ 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 5, 5, 7, 7, 8, 8, 9, 9, 10, 11, 12 ];
N = len(arr);
print(unique(arr, N));
# This code is contributed by Rajput-Ji
C#
// C# code to implement the above approach
using System;
public class GFG{
// Variable to store the number
// of unique elements
static int cnt = 0;
// Function to find the number
// of unique elements
static void UniqueElements(int []arr, int s,
int e, bool isDuplicate)
{
// Both start and end are same
if (arr[s] == arr[e]) {
// If the element is duplicate
if (isDuplicate == false) {
cnt++;
}
}
else {
int mid = s + (e - s) / 2;
UniqueElements(arr, s, mid, isDuplicate);
UniqueElements(arr, mid + 1, e,
arr[mid] == arr[mid + 1]);
}
}
// Function to count the number
// of unique elements
static int unique(int []arr, int N)
{
UniqueElements(arr, 0, N - 1, false);
return cnt;
}
// Driver Code
public static void Main(String[] args)
{
int []arr = { 1, 1, 1, 1, 1, 1, 2, 2, 2,
2, 3, 5, 5, 7, 7, 8, 8, 9,
9, 10, 11, 12 };
int N = arr.Length;
Console.Write(unique(arr, N));
}
}
// This code is contributed by shikhasingrajput
Javascript
10
时间复杂度: 平均情况为 O(log(N))。最坏的情况为 O(N)。
辅助空间: O(1)