Find uncommon characters of the two strings
Find and print the uncommon characters of the two given strings in sorted order. Here uncommon character means that either the character is present in one string or it is present in another string but not in both. The strings contain only lowercase characters and can contain duplicates.
Source: Amazon Interview Experience | Set 355 (For 1 Year Experienced)
Examples:
Input: str1 = “characters”, str2 = “alphabets”
Output: b c l p r
Input: str1 = “geeksforgeeks”, str2 = “geeksquiz”
Output: f i o q r u z
Naive Approach: Using two loops, for each character of 1st string check whether it is present in the 2nd string or not. Likewise, for each character of 2nd string check whether it is present in the 1st string or not.
Note: In the practice area of gfg the string has to be sorted in order to match with the output.
Algorithm:
- Take two strings str1 and str2 as input.
- Initialize an empty string ans to store the uncommon characters.
- Initialize a boolean vector used of size 26 to keep track of characters already visited.
- Traverse str1 and for each character check if it is present in str2.
- If the character is not present in str2 and not already added to ans, then add it to ans and mark it as used.
- Traverse str2 and for each character check if it is present in str1.
- If the character is not present in str1 and not already added to ans, then add it to ans and mark it as used.
- Sort the ans string in lexicographical order.
- If ans is empty, print -1. Otherwise, print the contents of ans.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void findAndPrintUncommonChars(string str1, string str2)
{
string ans = "" ;
vector< int > used(26, false );
for ( int i = 0; i < str1.size(); i++) {
bool found = false ;
for ( int j = 0; j < str2.size(); j++) {
if (str1[i] == str2[j]) {
found = true ;
break ;
}
}
if (!found and !used[str1[i] - 'a' ]) {
used[str1[i] - 'a' ] = true ;
ans += str1[i];
}
}
for ( int i = 0; i < str2.size(); i++) {
bool found = false ;
for ( int j = 0; j < str1.size(); j++) {
if (str2[i] == str1[j]) {
found = true ;
break ;
}
}
if (!found and !used[str2[i] - 'a' ]) {
used[str2[i] - 'a' ] = true ;
ans += str2[i];
}
}
sort(ans.begin(), ans.end());
if (ans.size() == 0)
cout << "-1" ;
else
cout << ans << " " ;
}
int main()
{
string str1 = "characters" ;
string str2 = "alphabets" ;
findAndPrintUncommonChars(str1, str2);
return 0;
}
|
Java
import java.util.*;
public class Solution
{
static void findAndPrintUncommonChars(String str1,
String str2)
{
String ans = "" ;
boolean [] used = new boolean [ 26 ];
for ( int i = 0 ; i < str1.length(); i++)
{
boolean found = false ;
for ( int j = 0 ; j < str2.length(); j++)
{
if (str1.charAt(i) == str2.charAt(j)) {
found = true ;
break ;
}
}
if (!found && !used[str1.charAt(i) - 'a' ]) {
used[str1.charAt(i) - 'a' ] = true ;
ans += str1.charAt(i);
}
}
for ( int i = 0 ; i < str2.length(); i++)
{
boolean found = false ;
for ( int j = 0 ; j < str1.length(); j++)
{
if (str2.charAt(i) == str1.charAt(j)) {
found = true ;
break ;
}
}
if (!found && !used[str2.charAt(i) - 'a' ]) {
used[str2.charAt(i) - 'a' ] = true ;
ans += str2.charAt(i);
}
}
char tempArray[] = ans.toCharArray();
Arrays.sort(tempArray);
ans = new String(tempArray);
if (ans.length() == 0 )
System.out.println( "-1" );
else
System.out.println(ans + " " );
}
public static void main(String[] args)
{
String str1 = "characters" ;
String str2 = "alphabets" ;
findAndPrintUncommonChars(str1, str2);
}
}
|
Python3
def findAndPrintUncommonChars(str1, str2):
ans = ""
used = [ False ] * 26
for i in range ( len (str1)):
found = False
for j in range ( len (str2)):
if str1[i] = = str2[j]:
found = True
break
if not found and not used[ ord (str1[i]) - ord ( 'a' )]:
used[ ord (str1[i]) - ord ( 'a' )] = True
ans + = str1[i]
for i in range ( len (str2)):
found = False
for j in range ( len (str1)):
if str2[i] = = str1[j]:
found = True
break
if not found and not used[ ord (str2[i]) - ord ( 'a' )]:
used[ ord (str2[i]) - ord ( 'a' )] = True
ans + = str2[i]
ans = "".join( sorted (ans))
if len (ans) = = 0 :
print ( "-1" )
else :
print (ans)
str1 = "characters"
str2 = "alphabets"
findAndPrintUncommonChars(str1, str2)
|
C#
using System;
public class GFG {
static void findAndPrintUncommonChars( string str1,
string str2)
{
string ans = "" ;
bool [] used = new bool [26];
for ( int i = 0; i < str1.Length; i++) {
bool found = false ;
for ( int j = 0; j < str2.Length; j++) {
if (str1[i] == str2[j]) {
found = true ;
break ;
}
}
if (!found && !used[str1[i] - 'a' ]) {
used[str1[i] - 'a' ] = true ;
ans += str1[i];
}
}
for ( int i = 0; i < str2.Length; i++) {
bool found = false ;
for ( int j = 0; j < str1.Length; j++) {
if (str2[i] == str1[j]) {
found = true ;
break ;
}
}
if (!found && !used[str2[i] - 'a' ]) {
used[str2[i] - 'a' ] = true ;
ans += str2[i];
}
}
char [] tempArray = ans.ToCharArray();
Array.Sort(tempArray);
ans = new String(tempArray);
if (ans.Length == 0)
Console.WriteLine( "-1" );
else
Console.WriteLine(ans + " " );
}
public static void Main( string [] args)
{
string str1 = "characters" ;
string str2 = "alphabets" ;
findAndPrintUncommonChars(str1, str2);
}
}
|
Javascript
function findAndPrintUncommonChars(str1, str2) {
let ans = "" ;
let used = new Array(26).fill( false );
for (let i = 0; i < str1.length; i++) {
let found = false ;
for (let j = 0; j < str2.length; j++) {
if (str1[i] === str2[j]) {
found = true ;
break ;
}
}
if (!found && !used[str1.charCodeAt(i) - 97]) {
used[str1.charCodeAt(i) - 97] = true ;
ans += str1[i];
}
}
for (let i = 0; i < str2.length; i++) {
let found = false ;
for (let j = 0; j < str1.length; j++) {
if (str2[i] === str1[j]) {
found = true ;
break ;
}
}
if (!found && !used[str2.charCodeAt(i) - 97]) {
used[str2.charCodeAt(i) - 97] = true ;
ans += str2[i];
}
}
ans = ans.split( '' ).sort().join( '' );
if (ans.length === 0) {
console.log( "-1" );
}
else {
console.log(ans);
}
}
let str1 = "characters" ;
let str2 = "alphabets" ;
findAndPrintUncommonChars(str1, str2);
|
Time Complexity: O(n1*n2)
Auxiliary Space: O(1), as a constant-size array is used to handle duplicates.
Efficient Approach: An efficient approach is to use hashing.
- Use a hash table of size 26 for all the lowercase characters.
- Initially, mark the presence of each character as ‘0’ (denoting that the character is not present in both strings).
- Traverse the 1st string and mark the presence of each character of 1st string as ‘1’ (denoting 1st string) in the hash table.
- Now, traverse the 2nd string. For each character of the 2nd string, check whether its presence in the hash table is ‘1’ or not. If it is ‘1’, then mark its presence as ‘-1’ (denoting that the character is common to both the strings), else mark its presence as ‘2’ (denoting 2nd string).
The below image is a dry run of the above approach:
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
const int MAX_CHAR = 26;
void findAndPrintUncommonChars(string str1, string str2)
{
int present[MAX_CHAR];
for ( int i=0; i<MAX_CHAR; i++)
present[i] = 0;
int l1 = str1.size();
int l2 = str2.size();
for ( int i=0; i<l1; i++)
present[str1[i] - 'a' ] = 1;
for ( int i=0; i<l2; i++)
{
if (present[str2[i] - 'a' ] == 1
|| present[str2[i] - 'a' ] == -1)
present[str2[i] - 'a' ] = -1;
else
present[str2[i] - 'a' ] = 2;
}
for ( int i=0; i<MAX_CHAR; i++)
if (present[i] == 1 || present[i] == 2 )
cout << ( char (i + 'a' )) << " " ;
}
int main()
{
string str1 = "characters" ;
string str2 = "alphabets" ;
findAndPrintUncommonChars(str1, str2);
return 0;
}
|
Java
import java.io.*;
class GFG
{
static int MAX_CHAR = 26 ;
static void findAndPrintUncommonChars(String str1,
String str2)
{
int present[] = new int [MAX_CHAR];
for ( int i = 0 ; i < MAX_CHAR; i++)
{
present[i] = 0 ;
}
int l1 = str1.length();
int l2 = str2.length();
for ( int i = 0 ; i < l1; i++)
{
present[str1.charAt(i) - 'a' ] = 1 ;
}
for ( int i = 0 ; i < l2; i++)
{
if (present[str2.charAt(i) - 'a' ] == 1
|| present[str2.charAt(i) - 'a' ] == - 1 )
{
present[str2.charAt(i) - 'a' ] = - 1 ;
}
else
{
present[str2.charAt(i) - 'a' ] = 2 ;
}
}
for ( int i = 0 ; i < MAX_CHAR; i++)
{
if (present[i] == 1 || present[i] == 2 )
{
System.out.print(( char ) (i + 'a' ) + " " );
}
}
}
public static void main(String[] args)
{
String str1 = "characters" ;
String str2 = "alphabets" ;
findAndPrintUncommonChars(str1, str2);
}
}
|
Python 3
MAX_CHAR = 26
def findAndPrintUncommonChars(str1, str2):
present = [ 0 ] * MAX_CHAR
for i in range ( 0 , MAX_CHAR):
present[i] = 0
l1 = len (str1)
l2 = len (str2)
for i in range ( 0 , l1):
present[ ord (str1[i]) - ord ( 'a' )] = 1
for i in range ( 0 , l2):
if (present[ ord (str2[i]) - ord ( 'a' )] = = 1 or
present[ ord (str2[i]) - ord ( 'a' )] = = - 1 ):
present[ ord (str2[i]) - ord ( 'a' )] = - 1
else :
present[ ord (str2[i]) - ord ( 'a' )] = 2
for i in range ( 0 , MAX_CHAR):
if (present[i] = = 1 or present[i] = = 2 ):
print ( chr (i + ord ( 'a' )), end = " " )
if __name__ = = "__main__" :
str1 = "characters"
str2 = "alphabets"
findAndPrintUncommonChars(str1, str2)
|
C#
using System;
class GFG
{
static int MAX_CHAR = 26;
static void findAndPrintUncommonChars(String str1,
String str2)
{
int []present = new int [MAX_CHAR];
for ( int i = 0; i < MAX_CHAR; i++)
{
present[i] = 0;
}
int l1 = str1.Length;
int l2 = str2.Length;
for ( int i = 0; i < l1; i++)
{
present[str1[i] - 'a' ] = 1;
}
for ( int i = 0; i < l2; i++)
{
if (present[str2[i] - 'a' ] == 1
|| present[str2[i] - 'a' ] == -1)
{
present[str2[i] - 'a' ] = -1;
}
else
{
present[str2[i] - 'a' ] = 2;
}
}
for ( int i = 0; i < MAX_CHAR; i++)
{
if (present[i] == 1 || present[i] == 2)
{
Console.Write(( char ) (i + 'a' ) + " " );
}
}
}
public static void Main(String[] args)
{
String str1 = "characters" ;
String str2 = "alphabets" ;
findAndPrintUncommonChars(str1, str2);
}
}
|
Javascript
<script>
var MAX_CHAR = 26;
function findAndPrintUncommonChars(str1, str2)
{
var present = Array(MAX_CHAR);
for ( var i = 0; i < MAX_CHAR; i++)
present[i] = 0;
var l1 = str1.length;
var l2 = str2.length;
for ( var i = 0; i < l1; i++)
present[str1[i].charCodeAt(0) - 'a' .charCodeAt(0)] = 1;
for ( var i = 0; i < l2; i++)
{
if (present[str2[i].charCodeAt(0) - 'a' .charCodeAt(0)] == 1
|| present[str2[i].charCodeAt(0) - 'a' .charCodeAt(0)] == -1)
present[str2[i].charCodeAt(0) - 'a' .charCodeAt(0)] = -1;
else
present[str2[i].charCodeAt(0) - 'a' .charCodeAt(0)] = 2;
}
for ( var i=0; i<MAX_CHAR; i++)
if (present[i] == 1 || present[i] == 2 )
document.write( (String.fromCharCode(i + 'a' .charCodeAt(0))) + " " );
}
var str1 = "characters" ;
var str2 = "alphabets" ;
findAndPrintUncommonChars(str1, str2);
</script>
|
Time Complexity: O(m + n), where m and n are the sizes of the two strings respectively.
Auxiliary Space: O(1), no any other extra space is required, so it is a constant.
Another Map-based approach:
- Take two maps and initialize their value as 0.
- traverse the first string, for each character present in first string, set 1 in the 1st map.
- Do the same for second string also.
- Iterate through all 26 characters, if the xor of map 1 and map 2 is 1 then it is present in one of the string only. i.e those characters are uncommon characters. Add them in the result string.
- return the result string, if the string is empty, return -1.
This approach is contributed by Bibhash Ghosh.
Below is the implementation of the above approach:
C++
#include<bits/stdc++.h>
using namespace std;
string UncommonChars(string a, string b)
{
int mp1[26] = {0}, mp2[26] = {0};
int n = a.size(), m = b.size();
for ( auto &x: a){
mp1[x- 'a' ] = 1;
}
for ( auto &x: b){
mp2[x- 'a' ] = 1;
}
string chars = "" ;
for ( int i = 0; i < 26; ++i){
if (mp1[i]^mp2[i])
chars+= char (i+ 'a' );
}
if (chars == "" )
return "-1" ;
else
return chars;
}
int main(){
string a = "geeksforgeeks" ;
string b = "geeksquiz" ;
string result = UncommonChars(a,b);
cout << result << endl;
return 0;
}
|
Java
import java.io.*;
class GFG {
static int MAX_CHAR = 26 ;
static String UncommonChars(String a, String b)
{
int mp1[] = new int [MAX_CHAR];
int mp2[] = new int [MAX_CHAR];
int n = a.length();
int m = b.length();
for ( int i = 0 ; i < n; i++) {
mp1[a.charAt(i) - 'a' ] = 1 ;
}
for ( int i = 0 ; i < m; i++) {
mp2[b.charAt(i) - 'a' ] = 1 ;
}
String chars = "" ;
for ( int i = 0 ; i < 26 ; i++) {
if ((mp1[i] ^ mp2[i]) != 0 ) {
chars += ( char )(i + 'a' );
}
}
if (chars == "" )
return "-1" ;
else
return chars;
}
public static void main(String[] args)
{
String a = "geeksforgeeks" ;
String b = "geeksquiz" ;
String result = UncommonChars(a, b);
System.out.print(result);
}
}
|
Python3
def uncommon_chars(a: str , b: str ) - > str :
mp1 = [ 0 ] * 26
mp2 = [ 0 ] * 26
n = len (a)
m = len (b)
for x in a:
mp1[ ord (x) - ord ( 'a' )] = 1
for x in b:
mp2[ ord (x) - ord ( 'a' )] = 1
chars = ""
for i in range ( 26 ):
if mp1[i] ^ mp2[i]:
chars + = chr (i + ord ( 'a' ))
if chars = = "":
return "-1"
else :
return chars
a = "geeksforgeeks"
b = "geeksquiz"
result = uncommon_chars(a, b)
print (result)
|
C#
using System;
public static class GFG {
public static string UncommonChars( string a, string b)
{
int [] mp1 = new int [26];
int [] mp2 = new int [26];
int n = a.Length;
int m = b.Length;
foreach ( var x in a) { mp1[x - 'a' ] = 1; }
foreach ( var x in b) { mp2[x - 'a' ] = 1; }
string chars = "" ;
for ( int i = 0; i < 26; ++i) {
if ((mp1[i] ^ mp2[i]) != 0) {
chars += ( char )(i + 'a' );
}
}
if (chars == "" ) {
return "-1" ;
}
else {
return chars;
}
}
public static void Main()
{
string a = "geeksforgeeks" ;
string b = "geeksquiz" ;
string result = UncommonChars(a, b);
Console.Write(result);
Console.Write( "\n" );
}
}
|
Javascript
function UncommonChars(a, b)
{
let mp1 = [], mp2 = [];
for (let i = 0; i < 26; i++)
{
mp1.push(0);
mp2.push(0);
}
let n = a.length, m = b.length;
for (let i = 0; i < n; i++) {
let index = a.charCodeAt(i) - 97;
mp1[index] = 1;
}
for (let i = 0; i < m; i++)
{
let index = b.charCodeAt(i) - 97;
mp2[index] = 1;
}
let chars = "" ;
for (let i = 0; i < 26; ++i){
if (mp1[i]^mp2[i])
{
let char = String.fromCharCode(97+i);
chars += char;
}
}
if (chars == "" )
return "-1" ;
else
return chars;
}
let a = "geeksforgeeks" ;
let b = "geeksquiz" ;
let result = UncommonChars(a,b);
console.log(result);
|
Time Complexity: O(m+n), Where m is the length of the first string and n is the length of second string.
Auxiliary Space: O(1), no any other extra space is required, so it is a constant.
Another Python-specific approach using set() and symmetric_difference().
In this approach we will convert both the strings into sets and use symmetric_diffference() to find out the uncommon characters between them.
C++
#include <iostream>
#include <string>
#include <algorithm>
#include <iterator>
#include <set>
using namespace std;
int main() {
string str1 = "characters" ;
string str2 = "alphabets" ;
set< char > set1(str1.begin(), str1.end());
set< char > set2(str2.begin(), str2.end());
string result1;
set_symmetric_difference(set1.begin(), set1.end(), set2.begin(), set2.end(),
inserter(result1, result1.begin()));
cout << result1 << endl;
string result2;
set_symmetric_difference(set1.begin(), set1.end(), set2.begin(), set2.end(),
inserter(result2, result2.begin()));
cout << result2 << endl;
return 0;
}
|
Java
import java.util.HashSet;
import java.util.Set;
public class Main {
public static void main(String[] args) {
String str1 = "characters" ;
String str2 = "alphabets" ;
Set<Character> set1 = new HashSet<>();
Set<Character> set2 = new HashSet<>();
for ( int i = 0 ; i < str1.length(); i++) {
set1.add(str1.charAt(i));
}
for ( int i = 0 ; i < str2.length(); i++) {
set2.add(str2.charAt(i));
}
Set<Character> diff = new HashSet<>(set1);
diff.addAll(set2);
Set<Character> temp = new HashSet<>(set1);
temp.retainAll(set2);
diff.removeAll(temp);
StringBuilder sb = new StringBuilder();
for ( char ch : diff) {
sb.append(ch);
}
String result = sb.toString();
System.out.println(result);
}
}
|
Python3
str1 = "characters"
str2 = "alphabets"
str1 = set (str1)
str2 = set (str2)
print ("".join( sorted (str1 ^ str2)))
print ("".join( sorted (str1.symmetric_difference(str2))))
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
string str1 = "characters" ;
string str2 = "alphabets" ;
var set1 = new HashSet< char >(str1);
var set2 = new HashSet< char >(str2);
var result1 = new string (set1.Except(set2).Union(set2.Except(set1)).ToArray());
Console.WriteLine( new string (result1.OrderBy(c => c).ToArray()));
var result2 = new HashSet< char >(set1);
result2.SymmetricExceptWith(set2);
Console.WriteLine( new string (result2.OrderBy(c => c).ToArray()));
}
}
|
Javascript
let str1 = "characters" ;
let str2 = "alphabets" ;
let set1 = new Set();
let set2 = new Set();
for (let i = 0; i < str1.length; i++) {
set1.add(str1.charAt(i));
}
for (let i = 0; i < str2.length; i++) {
set2.add(str2.charAt(i));
}
let diff = new Set([...set1, ...set2]);
for (let char of set1) {
if (set2.has(char)) {
diff. delete (char);
}
}
let result = [...diff].sort().join( "" );
console.log(result);
|
Time Complexity – O(nlogn) # Just for the sorted function.
Space Complexity – O(1) # No extra space has been used
Last Updated :
21 Sep, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...