Print all Unique Strings present in a given Array
Last Updated :
21 Mar, 2023
Given an array of strings arr[], the task is to print all unique strings that are present in the given array.
Examples:
Input: arr[] = { “geeks”, “geek”, “ab”, “geek” “code”, “karega” }
Output: geeks ab code karega
Explanation:
The frequency of the string “geeks” is 1.
The frequency of the string “geek” is 2.
The frequency of the string “ab” is 1.
The frequency of the string “code” is 1.
The frequency of the string “karega” is 1.
Therefore, the required output is “geeks ab code karega”
Input: arr[] = { “abcde”, “abcd”, “abcd”, “co” “”, “code” }
Output: abcde co code
Naive Approach: The simplest approach to solve this problem is to traverse the array for every string encountered, check if that string occurs in the remaining array or not. Print those strings which are occurring only once in the array.
Time Complexity: O(N2 * M), where M is the maximum length of the string
Auxiliary Space: O(1)
Efficient Approach using STL:
Another approach to print all the unique elements in array is by using unordered_map.
Steps involved in this approach are as follows:
- In first step an unordered_map(freqMap) is declared, which will be used to store the frequency of each string in the array.
- Then we run a for loop for all the elements of the array. In each iteration, the frequency of the i-th string in the array is incremented in the map.
- Then we iterate through this unordered_map and print all the strings which is present only one time in the array.
Below is the code for the above approach.
C++
#include <bits/stdc++.h>
using namespace std;
void printUniqueStrings(vector<string> arr) {
unordered_map<string, int > freqMap;
for ( auto str : arr) {
++freqMap[str];
}
for ( auto p : freqMap) {
if (p.second == 1) {
std::cout << p.first << " " ;
}
}
}
int main() {
vector<string> arr = { "geeks" , "for" ,
"geek" , "ab" , "geek" ,
"for" , "code" , "karega" };
printUniqueStrings(arr);
return 0;
}
|
Java
import java.util.*;
public class Main {
static void printUniqueStrings(String[] arr) {
Map<String, Integer> freqMap = new HashMap<>();
for (String str : arr) {
freqMap.put(str, freqMap.getOrDefault(str, 0 ) + 1 );
}
for (Map.Entry<String, Integer> entry : freqMap.entrySet()) {
if (entry.getValue() == 1 ) {
System.out.print(entry.getKey() + " " );
}
}
}
public static void main(String[] args) {
String[] arr = { "geeks" , "for" , "geek" , "ab" , "geek" , "for" , "code" , "karega" };
printUniqueStrings(arr);
}
}
|
Python3
def printUniqueStrings(arr):
freqMap = {}
for str in arr:
freqMap[ str ] = freqMap.get( str , 0 ) + 1
for key, value in freqMap.items():
if value = = 1 :
print (key, end = " " )
arr = [ "geeks" , "for" , "geek" , "ab" , "geek" , "for" , "code" , "karega" ]
printUniqueStrings(arr)
|
C#
using System;
using System.Collections.Generic;
class MainClass
{
static void printUniqueStrings( string [] arr) {
Dictionary< string , int > freqMap = new Dictionary< string , int >();
foreach ( string str in arr) {
freqMap[str] = freqMap.GetValueOrDefault(str, 0) + 1;
}
foreach (KeyValuePair< string , int > entry in freqMap) {
if (entry.Value == 1) {
Console.Write(entry.Key + " " );
}
}
}
public static void Main( string [] args) {
string [] arr = { "geeks" , "for" , "geek" , "ab" , "geek" , "for" , "code" , "karega" };
printUniqueStrings(arr);
}
}
|
Javascript
function printUniqueStrings(arr) {
let freqMap = {};
for (let str of arr) {
freqMap[str] = (freqMap[str] || 0) + 1;
}
for (let [key, value] of Object.entries(freqMap)) {
if (value === 1) {
console.log(key + " " );
}
}
}
let arr = [ "geeks" , "for" , "geek" , "ab" , "geek" , "for" , "code" , "karega" ];
printUniqueStrings(arr);
|
Output
karega code ab geeks
Time Complexity: O(N*M) where N is the number of strings in the array and M is the maximum length of the strings.
Space Complexity: O(N*M)
Efficient Approach: The above approach can be optimized using Trie. The idea is to traverse the array and for every ith string in the array, check if arr[i] is present in the Trie or not. If found to be true, then mark arr[i] as duplicate array element. Otherwise, mark arr[i] as unique array element and insert arr[i] into the trie. Follow the steps below to solve the problem:
- Initialize an array, say isUniq[], to check if an array element is unique or not.
- Create a Trie having a root node, say root, to store the characters of each string present in the given array.
- Traverse the array using variable i and for every ith element, check if arr[i] is present in the Trie or not. IF found to be true, then update isUniq[i] to false.
- Otherwise, update isUniq[i] to true and insert arr[i] into the Trie.
- Finally, traverse the isUniq[] array using variable i and for every ith element, check if isUniq[i] is true or not. If found to be true, then print arr[i].
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
struct TrieNode {
int idx;
TrieNode* child[26];
TrieNode()
{
idx = -1;
for ( int i = 0; i < 26; i++) {
child[i] = NULL;
}
}
};
void Insert(TrieNode* root,
string str, int i)
{
int N = str.length();
for ( int i = 0; i < N; i++) {
if (!root->child[str[i] - 'a' ]) {
root->child[str[i] - 'a' ]
= new TrieNode();
}
root = root->child[str[i] - 'a' ];
}
root->idx = i;
}
int SearchString(TrieNode* root, string str)
{
int N = str.length();
for ( int i = 0; i < N; i++) {
if (!root->child[str[i] - 'a' ]) {
return -1;
}
root
= root->child[str[i] - 'a' ];
}
return root->idx;
}
void UtilUniqStr(vector<string>& arr, int N)
{
TrieNode* root = new TrieNode();
bool isUniq[N];
memset (isUniq, false , sizeof (isUniq));
Insert(root, arr[0], 0);
isUniq[0] = true ;
for ( int i = 1; i < N; i++) {
int idx = SearchString(root,
arr[i]);
if (idx == -1) {
isUniq[i] = true ;
Insert(root, arr[i], i);
}
else {
isUniq[idx] = false ;
}
}
for ( int i = 0; i < N; i++) {
if (isUniq[i]) {
cout << arr[i] << " " ;
}
}
}
int main()
{
vector<string> arr = { "geeks" , "for" ,
"geek" , "ab" , "geek" ,
"for" , "code" , "karega" };
int N = arr.size();
UtilUniqStr(arr, N);
return 0;
}
|
Java
import java.util.*;
public class GFG
{
static class TrieNode {
int idx;
TrieNode []child = new TrieNode[ 26 ];
TrieNode()
{
idx = - 1 ;
for ( int i = 0 ; i < 26 ; i++) {
child[i] = null ;
}
}
};
static void Insert(TrieNode root,
String str, int i)
{
int N = str.length();
for ( int j = 0 ; j < N; j++) {
if (root.child[str.charAt(j) - 'a' ]== null ) {
root.child[str.charAt(j) - 'a' ]
= new TrieNode();
}
root = root.child[str.charAt(j) - 'a' ];
}
root.idx = i;
}
static int SearchString(TrieNode root, String str)
{
int N = str.length();
for ( int i = 0 ; i < N; i++) {
if (root.child[str.charAt(i) - 'a' ] == null ) {
return - 1 ;
}
root
= root.child[str.charAt(i) - 'a' ];
}
return root.idx;
}
static void UtilUniqStr(String[] arr, int N)
{
TrieNode root = new TrieNode();
boolean []isUniq = new boolean [N];
Insert(root, arr[ 0 ], 0 );
isUniq[ 0 ] = true ;
for ( int i = 1 ; i < N; i++) {
int idx = SearchString(root,
arr[i]);
if (idx == - 1 ) {
isUniq[i] = true ;
Insert(root, arr[i], i);
}
else {
isUniq[idx] = false ;
}
}
for ( int i = 0 ; i < N; i++) {
if (isUniq[i]) {
System.out.print(arr[i]+ " " );
}
}
}
public static void main(String[] args)
{
String[] arr = { "geeks" , "for" ,
"geek" , "ab" , "geek" ,
"for" , "code" , "karega" };
int N = arr.length;
UtilUniqStr(arr, N);
}
}
|
Python3
root = None
class TrieNode:
def __init__( self ):
self .idx = - 1
self .child = [ None ] * 26
def Insert( str , i):
global root
N = len ( str )
root1 = root
for i in range (N):
if ( not root1.child[ ord ( str [i]) - ord ( 'a' )]):
root1.child[ ord ( str [i]) - ord ( 'a' )] = TrieNode()
root1 = root1.child[ ord ( str [i]) - ord ( 'a' )]
root1.idx = i
return root1
def SearchString( str ):
global root
root1 = root
N = len ( str )
for i in range (N):
if ( not root1.child[ ord ( str [i]) - ord ( 'a' )]):
return - 1
root1 = root1.child[ ord ( str [i]) - ord ( 'a' )]
return root1.idx
def UtilUniqStr(arr, N):
global root
root = TrieNode()
d = {}
for i in arr:
d[i] = d.get(i, 0 ) + 1
isUniq = [ False ] * N
Insert(arr[ 0 ], 0 )
isUniq[ 0 ] = True
for i in range ( 1 , N):
idx = SearchString(arr[i])
if (idx = = - 1 and d[arr[i]] = = 1 ):
isUniq[i] = True
Insert(arr[i], i)
else :
isUniq[idx] = False
for i in range (N):
if (isUniq[i]):
print (arr[i], end = " " )
if __name__ = = '__main__' :
arr = [ "geeks" , "for" , "geek" , "ab" , "geek" , "for" , "code" , "karega" ]
N = len (arr)
UtilUniqStr(arr, N)
|
C#
using System;
class GFG
{
class TrieNode {
public int idx;
public TrieNode []child = new TrieNode[26];
public TrieNode()
{
idx = -1;
for ( int i = 0; i < 26; i++) {
child[i] = null ;
}
}
};
static void Insert(TrieNode root,
String str, int i)
{
int N = str.Length;
for ( int j = 0; j < N; j++) {
if (root.child[str[j] - 'a' ] == null ) {
root.child[str[j] - 'a' ]
= new TrieNode();
}
root = root.child[str[j] - 'a' ];
}
root.idx = i;
}
static int SearchString(TrieNode root, String str)
{
int N = str.Length;
for ( int i = 0; i < N; i++) {
if (root.child[str[i] - 'a' ] == null ) {
return -1;
}
root
= root.child[str[i] - 'a' ];
}
return root.idx;
}
static void UtilUniqStr(String[] arr, int N)
{
TrieNode root = new TrieNode();
bool []isUniq = new bool [N];
Insert(root, arr[0], 0);
isUniq[0] = true ;
for ( int i = 1; i < N; i++) {
int idx = SearchString(root,
arr[i]);
if (idx == -1) {
isUniq[i] = true ;
Insert(root, arr[i], i);
}
else {
isUniq[idx] = false ;
}
}
for ( int i = 0; i < N; i++) {
if (isUniq[i]) {
Console.Write(arr[i] + " " );
}
}
}
public static void Main(String[] args)
{
String[] arr = { "geeks" , "for" ,
"geek" , "ab" , "geek" ,
"for" , "code" , "karega" };
int N = arr.Length;
UtilUniqStr(arr, N);
}
}
|
Javascript
<script>
class TrieNode
{
constructor()
{
this .idx = -1;
this .child = new Array(26);
for (let i = 0; i < 26; i++) {
this .child[i] = null ;
}
}
}
function Insert(root,str,i)
{
let N = str.length;
for (let j = 0; j < N; j++) {
if (root.child[str[j].charCodeAt(0) -
'a' .charCodeAt(0)]== null ) {
root.child[str[j].charCodeAt(0) -
'a' .charCodeAt(0)]
= new TrieNode();
}
root = root.child[str[j].charCodeAt(0) -
'a' .charCodeAt(0)];
}
root.idx = i;
}
function SearchString(root,str)
{
let N = str.length;
for (let i = 0; i < N; i++) {
if (root.child[str[i].charCodeAt(0) -
'a' .charCodeAt(0)] == null ) {
return -1;
}
root
= root.child[str[i].charCodeAt(0) -
'a' .charCodeAt(0)];
}
return root.idx;
}
function UtilUniqStr(arr,N)
{
let root = new TrieNode();
let isUniq = new Array(N);
Insert(root, arr[0], 0);
isUniq[0] = true ;
for (let i = 1; i < N; i++) {
let idx = SearchString(root,
arr[i]);
if (idx == -1) {
isUniq[i] = true ;
Insert(root, arr[i], i);
}
else {
isUniq[idx] = false ;
}
}
for (let i = 0; i < N; i++) {
if (isUniq[i]) {
document.write(arr[i]+ " " );
}
}
}
let arr=[ "geeks" , "for" ,
"geek" , "ab" , "geek" ,
"for" , "code" , "karega" ];
let N = arr.length;
UtilUniqStr(arr, N);
</script>
|
Output
geeks ab code karega
Time Complexity: O(N * M), where M is the maximum length of the string
Auxiliary Space: O(N * 26)
Share your thoughts in the comments
Please Login to comment...