Count of Unique elements in a very large sorted Array
Last Updated :
28 Feb, 2022
Given a sorted array arr[] of size N, the task is to find the number of unique elements in this array.
Note: The array is very large, and unique numbers are significantly less. i.e., (unique elements <<size of the array).
Examples:
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
Naive Approach: As the given array is sorted, one of the simple approaches will be traversing through all over the element and comparing them with the previous ones. If it is different, then count that element.
Time Complexity: O(N)
Auxiliary Space: O(1).
Approach based on Binary Search: The idea is the use Binary search because the array is sorted. Follow the steps mentioned below:
- Take the first number, then find its last occurrence or upper bound using binary search.
- Then count it as one unique element.
- Place pointer to next different element and repeat the same step.
Note: This algorithm is only effective when very few unique elements.
Below is the implementation of the above approach.
C++
#include <bits/stdc++.h>
using namespace std;
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;
}
return result + 1;
}
int unique( int arr[], int N)
{
int i = 0;
int count = 0;
while (i < N) {
i = nextIndex(arr, N, i, arr[i]);
count++;
}
return count;
}
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
class GFG {
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 ;
}
return result + 1 ;
}
static int unique( int arr[], int N) {
int i = 0 ;
int count = 0 ;
while (i < N) {
i = nextIndex(arr, N, i, arr[i]);
count++;
}
return count;
}
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
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
return result + 1
def unique(arr, N):
i = 0
count = 0
while (i < N):
i = nextIndex(arr, N, i, arr[i])
count + = 1
return count
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))
|
C#
using System;
using System.Collections.Generic;
public class GFG
{
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;
}
return result + 1;
}
static int unique( int [] arr, int N) {
int i = 0;
int count = 0;
while (i < N) {
i = nextIndex(arr, N, i, arr[i]);
count++;
}
return count;
}
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));
}
}
|
Javascript
<script>
function nextIndex(arr, N, l,
target) {
let result = -1;
let r = N - 1;
while (l <= r) {
let mid = l + Math.floor((r - l) / 2);
if (arr[mid] == target) {
result = mid;
l = mid + 1;
}
else if (arr[mid] > target)
r = mid - 1;
else
l = mid + 1;
}
return result + 1;
}
function unique(arr, N) {
let i = 0;
let count = 0;
while (i < N) {
i = nextIndex(arr, N, i, arr[i]);
count++;
}
return count;
}
let arr = [1, 1, 1, 1, 1, 1, 2, 2, 2,
2, 3, 5, 5, 7, 7, 8, 8, 9,
9, 10, 11, 12];
let N = arr.length;
document.write(unique(arr, N));
</script>
|
Time Complexity: K * logO(N). where K = no. of unique elements.
Auxiliary Space: O(1).
Approach based on Divide and Conquer: This problem can be solved using divide and conquer. Idea is:
- As duplicate elements are large, look at the first and last elements of this sorted array.
- If both are equal, it means only this element is present in the entire array, and it will be counted as one.
- If they are different, divide the array into two halves and repeat the above step for each array.
- The final count is the number of unique elements.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int cnt = 0;
void UniqueElements( int arr[], int s,
int e, bool isDuplicate)
{
if (arr[s] == arr[e]) {
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]);
}
}
int unique( int arr[], int N)
{
UniqueElements(arr, 0, N - 1, 0);
return cnt;
}
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
import java.util.*;
class GFG{
static int cnt = 0 ;
static void UniqueElements( int arr[], int s,
int e, boolean isDuplicate)
{
if (arr[s] == arr[e]) {
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 ]);
}
}
static int unique( int arr[], int N)
{
UniqueElements(arr, 0 , N - 1 , false );
return cnt;
}
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));
}
}
|
Python3
cnt = 0 ;
def UniqueElements(arr, s, e, isDuplicate):
global cnt
if (arr[s] = = arr[e]):
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 ]);
def unique(arr, N):
UniqueElements(arr, 0 , N - 1 , False );
return cnt;
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));
|
C#
using System;
public class GFG{
static int cnt = 0;
static void UniqueElements( int []arr, int s,
int e, bool isDuplicate)
{
if (arr[s] == arr[e]) {
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]);
}
}
static int unique( int []arr, int N)
{
UniqueElements(arr, 0, N - 1, false );
return cnt;
}
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));
}
}
|
Javascript
<script>
var cnt = 0;
function UniqueElements(arr , s,e, isDuplicate)
{
if (arr[s] == arr[e]) {
if (isDuplicate == false ) {
cnt++;
}
}
else {
var mid = s + parseInt((e - s) / 2);
UniqueElements(arr, s, mid, isDuplicate);
UniqueElements(arr, mid + 1, e,
arr[mid] == arr[mid + 1]);
}
}
function unique(arr , N)
{
UniqueElements(arr, 0, N - 1, false );
return cnt;
}
var arr = [ 1, 1, 1, 1, 1, 1, 2, 2, 2,
2, 3, 5, 5, 7, 7, 8, 8, 9,
9, 10, 11, 12 ];
var N = arr.length;
document.write(unique(arr, N));
</script>
|
Time Complexity: O(log(N)) for the average case.The worst case will be O(N).
Auxiliary Space: O(1)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...