Given an array of integers arr[], the task is to return the no of distinct elements in every prefix.
- The array will have positive and negative values. positive value means you have to append it into your data and negative value means you have to remove it from your data.
- If the element is not present in the data and you get the -ve of that element then no changes should occur.
Example:
Input: arr[] = [5, 5, 7, -5, -7, 1, 2, -2]
Output: [1, 1, 2, 2, 1, 2, 3, 2]
Explanation: Proper adding and removal of intgers will give this outputInput: arr[] = [9, 9, 3, -9, -3, -9]
Output: [1, 1, 2, 2, 1, 0]
Explanation: Proper adding and removal of intgers will give this output.
Table of Content
[Naive Approach] Simulation with Linear Search - O(nÂē) Time and O(n) Space
Maintain an array of current elements. For positive numbers, add only if not already present. For negative numbers, remove the corresponding positive element. Track distinct count after each operation.
- Initialize emptyÂ
data[]Â that is going to store distinct elements. - For each elementÂ
x in input array. - IfÂ
x is positive, searchÂdata[] forÂx.If not found, appendÂx toÂdata[] - IfÂ
x is negative, searchÂdata[] forÂ-x.If found, remove it fromÂdata[] - Store current size ofÂ
data[]Â intoÂans[]
#include <iostream>
#include <vector>
using namespace std;
// Returns number of distinct elements after each operation
vector<int> getDistinct(vector<int> &arr)
{
// Stores elements currently present in the data
vector<int> data;
// Stores answer for each prefix
vector<int> ans;
for (int x : arr)
{
if (x > 0)
{
// Check if element is already present
bool found = false;
for (int val : data)
{
if (val == x)
{
found = true;
break;
}
}
// Insert only if not already present
if (!found)
data.push_back(x);
}
else
{
int target = -x;
// Find and remove the element if present
for (int i = 0; i < data.size(); i++)
{
if (data[i] == target)
{
data.erase(data.begin() + i);
break;
}
}
}
// Current number of distinct elements
ans.push_back(data.size());
}
return ans;
}
int main()
{
vector<int> arr = {5, 3, -5, 2, -10};
vector<int> ans = getDistinct(arr);
for (int x : ans)
cout << x << " ";
return 0;
}
// Java program to find number of distinct elements after each operation
import java.util.*;
class GfG {
// Returns number of distinct elements after each operation
static List<Integer> getDistinct(List<Integer> arr) {
// Stores elements currently present in the data
List<Integer> data = new ArrayList<>();
// Stores answer for each prefix
List<Integer> ans = new ArrayList<>();
for (int x : arr) {
if (x > 0) {
// Check if element is already present
boolean found = false;
for (int val : data) {
if (val == x) {
found = true;
break;
}
}
// Insert only if not already present
if (!found)
data.add(x);
} else {
int target = -x;
// Find and remove the element if present
for (int i = 0; i < data.size(); i++) {
if (data.get(i) == target) {
data.remove(i);
break;
}
}
}
// Current number of distinct elements
ans.add(data.size());
}
return ans;
}
public static void main(String[] args) {
List<Integer> arr = Arrays.asList(5, 3, -5, 2, -10);
List<Integer> ans = getDistinct(arr);
for (int x : ans) {
System.out.print(x + " ");
}
}
}
# Python program to find number of distinct elements after each operation
def getDistinct(arr):
# Stores elements currently present in the data
data = []
# Stores answer for each prefix
ans = []
for x in arr:
if x > 0:
# Insert only if not already present
if x not in data:
data.append(x)
else:
target = -x
# Remove the element if present
if target in data:
data.remove(target)
# Current number of distinct elements
ans.append(len(data))
return ans
# Driver code
if __name__ == "__main__":
arr = [5, 3, -5, 2, -10]
ans = getDistinct(arr)
print(' '.join(map(str, ans)))
// C# program to find number of distinct elements after each operation
using System;
using System.Collections.Generic;
class GfG {
// Returns number of distinct elements after each operation
static List<int> getDistinct(List<int> arr) {
// Stores elements currently present in the data
List<int> data = new List<int>();
// Stores answer for each prefix
List<int> ans = new List<int>();
foreach (int x in arr) {
if (x > 0) {
// Check if element is already present
bool found = false;
foreach (int val in data) {
if (val == x) {
found = true;
break;
}
}
// Insert only if not already present
if (!found)
data.Add(x);
} else {
int target = -x;
// Find and remove the element if present
for (int i = 0; i < data.Count; i++) {
if (data[i] == target) {
data.RemoveAt(i);
break;
}
}
}
// Current number of distinct elements
ans.Add(data.Count);
}
return ans;
}
static void Main(string[] args) {
List<int> arr = new List<int> { 5, 3, -5, 2, -10 };
List<int> ans = getDistinct(arr);
foreach (int x in ans) {
Console.Write(x + " ");
}
}
}
// JavaScript program to find number of distinct elements after each operation
function getDistinct(arr) {
// Stores elements currently present in the data
let data = [];
// Stores answer for each prefix
let ans = [];
for (let x of arr) {
if (x > 0) {
// Insert only if not already present
if (!data.includes(x)) {
data.push(x);
}
} else {
let target = -x;
// Remove the element if present
let index = data.indexOf(target);
if (index !== -1) {
data.splice(index, 1);
}
}
// Current number of distinct elements
ans.push(data.length);
}
return ans;
}
// Driver code
const arr = [5, 3, -5, 2, -10];
const ans = getDistinct(arr);
console.log(ans.join(' '));
Output
1 2 1 2 2
[Optimal Approach] Hashing for O(1) Operations - O(n) Time and O(n) Space
Use a hash set to track current elements. For positive numbers, add to set. For negative numbers, remove the corresponding positive number. Set size after each step gives number of distinct elements.
- Initialize empty setÂ
st and empty arrayÂans - For each elementÂ
x in input array. IfÂx is positive, insertÂx intoÂst - IfÂ
x is negative, removeÂ-x fromÂst - Store current size ofÂ
st intoÂans
#include <iostream>
#include <vector>
#include <unordered_set>
using namespace std;
// Returns number of distinct elements after each operation
vector<int> getDistinct(vector<int> &arr)
{
// Stores elements currently present in the data
unordered_set<int> st;
// Stores answer for each prefix
vector<int> ans;
for (int x : arr)
{
if (x > 0)
{
// Add the element into the data
st.insert(x);
}
else
{
// Remove the element if present
st.erase(-x);
}
// Current number of distinct elements
ans.push_back(st.size());
}
return ans;
}
int main()
{
vector<int> arr = {5, 3, -5, 2, -10};
vector<int> ans = getDistinct(arr);
for (int x : ans)
cout << x << " ";
return 0;
}
// Java program to find number of distinct elements after each operation using HashSet
import java.util.*;
class GfG {
// Returns number of distinct elements after each operation
static List<Integer> getDistinct(List<Integer> arr) {
// Stores elements currently present in the data
Set<Integer> st = new HashSet<>();
// Stores answer for each prefix
List<Integer> ans = new ArrayList<>();
for (int x : arr) {
if (x > 0) {
// Add the element into the data
st.add(x);
} else {
// Remove the element if present
st.remove(-x);
}
// Current number of distinct elements
ans.add(st.size());
}
return ans;
}
public static void main(String[] args) {
List<Integer> arr = Arrays.asList(5, 3, -5, 2, -10);
List<Integer> ans = getDistinct(arr);
for (int x : ans) {
System.out.print(x + " ");
}
}
}
# Python program to find number of distinct elements after each operation using set
def getDistinct(arr):
# Stores elements currently present in the data
st = set()
# Stores answer for each prefix
ans = []
for x in arr:
if x > 0:
# Add the element into the data
st.add(x)
else:
# Remove the element if present
st.discard(-x) # discard removes if exists, no error if not
# Current number of distinct elements
ans.append(len(st))
return ans
# Driver code
if __name__ == "__main__":
arr = [5, 3, -5, 2, -10]
ans = getDistinct(arr)
print(' '.join(map(str, ans)))
// C# program to find number of distinct elements after each operation using HashSet
using System;
using System.Collections.Generic;
class GfG {
// Returns number of distinct elements after each operation
static List<int> getDistinct(List<int> arr) {
// Stores elements currently present in the data
HashSet<int> st = new HashSet<int>();
// Stores answer for each prefix
List<int> ans = new List<int>();
foreach (int x in arr) {
if (x > 0) {
// Add the element into the data
st.Add(x);
} else {
// Remove the element if present
st.Remove(-x);
}
// Current number of distinct elements
ans.Add(st.Count);
}
return ans;
}
static void Main(string[] args) {
List<int> arr = new List<int> { 5, 3, -5, 2, -10 };
List<int> ans = getDistinct(arr);
foreach (int x in ans) {
Console.Write(x + " ");
}
}
}
// JavaScript program to find number of distinct elements after each operation using Set
function getDistinct(arr) {
// Stores elements currently present in the data
let st = new Set();
// Stores answer for each prefix
let ans = [];
for (let x of arr) {
if (x > 0) {
// Add the element into the data
st.add(x);
} else {
// Remove the element if present
st.delete(-x);
}
// Current number of distinct elements
ans.push(st.size);
}
return ans;
}
// Driver code
const arr = [5, 3, -5, 2, -10];
const ans = getDistinct(arr);
console.log(ans.join(' '));
Output
1 2 1 2 2