Find uncommon characters of the two strings
Last Updated :
16 Sep, 2024
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.
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] O(n^2) Time and O(1) Space:
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.
Below is the implementation of the above approach:
C++
// C++ implementation to find the uncommon
// characters of the two strings
#include <bits/stdc++.h>
using namespace std;
// function to find the uncommon characters
// of the two strings
string UncommonChars(string str1, string str2) {
// to store the answer
string ans = "";
// to handle the case of duplicates
vector<int> used(26, false);
// check first for str1
for (int i = 0; i < str1.size(); i++) {
// keeping a flag variable
bool found = false;
for (int j = 0; j < str2.size(); j++) {
// if found change the flag
// and break from loop
if (str1[i] == str2[j]) {
found = true;
break;
}
}
// if duplicate character not found
// then add it to ans
if (!found and !used[str1[i] - 'a']) {
used[str1[i] - 'a'] = true;
ans += str1[i];
}
}
// now check for str2
for (int i = 0; i < str2.size(); i++) {
// keeping a flag variable
bool found = false;
for (int j = 0; j < str1.size(); j++) {
// if found change the flag
// and break from loop
if (str2[i] == str1[j]) {
found = true;
break;
}
}
// if duplicate character not found
// then add it to ans
if (!found and !used[str2[i] - 'a']) {
used[str2[i] - 'a'] = true;
ans += str2[i];
}
}
// to match with output
sort(ans.begin(), ans.end());
// if not found any character
if (ans.size() == 0)
return "-1";
// else print the answer
else
return ans;
}
int main() {
string str1 = "characters";
string str2 = "alphabets";
cout<<UncommonChars(str1, str2);
return 0;
}
Java
import java.util.Arrays;
public class UncommonCharacters {
// Function to find the uncommon characters of the two strings
public static String uncommonChars(String str1, String str2) {
StringBuilder ans = new StringBuilder();
// to handle the case of duplicates
boolean[] used = new boolean[26];
// check first for str1
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.append(str1.charAt(i));
}
}
// now check for str2
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.append(str2.charAt(i));
}
}
// sort the answer
char[] ansArray = ans.toString().toCharArray();
Arrays.sort(ansArray);
// if not found any character
if (ansArray.length == 0)
return "-1";
return new String(ansArray);
}
public static void main(String[] args) {
String str1 = "characters";
String str2 = "alphabets";
System.out.println(uncommonChars(str1, str2));
}
}
Python
def uncommon_chars(str1, str2):
ans = ""
# to handle the case of duplicates
used = [False] * 26
# check first for str1
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]
# now check for str2
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:
return "-1"
return ans
if __name__ == "__main__":
str1 = "characters"
str2 = "alphabets"
print(uncommon_chars(str1, str2))
C#
using System;
using System.Collections.Generic;
using System.Linq;
public class Program {
public static string UncommonChars(string str1, string str2) {
string ans = "";
// to handle the case of duplicates
bool[] used = new bool[26];
// check first for str1
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];
}
}
// now check for str2
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];
}
}
// sort the answer
char[] ansArray = ans.ToCharArray();
Array.Sort(ansArray);
if (ansArray.Length == 0)
return "-1";
return new string(ansArray);
}
public static void Main(string[] args)
{
string str1 = "characters";
string str2 = "alphabets";
Console.WriteLine(UncommonChars(str1, str2));
}
}
JavaScript
function uncommonChars(str1, str2) {
let ans = "";
// to handle the case of duplicates
let used = Array(26).fill(false);
// check first for str1
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) - 'a'.charCodeAt(0)]) {
used[str1.charCodeAt(i) - 'a'.charCodeAt(0)] = true;
ans += str1[i];
}
}
// now check for str2
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) - 'a'.charCodeAt(0)]) {
used[str2.charCodeAt(i) - 'a'.charCodeAt(0)] = true;
ans += str2[i];
}
}
// sort the answer
ans = ans.split('').sort().join('');
if (ans.length === 0)
return "-1";
return ans;
}
let str1 = "characters";
let str2 = "alphabets";
console.log(uncommonChars(str1, str2));
Time Complexity: O(n1*n2)
Auxiliary Space: O(1), as a constant-size array is used to handle duplicates.
[Optimized Approach] Using Hashing O(n) Time and O(1) Space:
The approach involves using a hash table to keep track of character presence from both strings. First, iterate through the first string and mark each character’s presence in the hash table. Then, iterate through the second string, updating the hash table to mark characters already seen in the first string as common and new characters as unique to the second string. Finally, collect and sort all characters marked as unique to either string, and return them; if no such characters are found, return “-1”.
The below image is a dry run of the above approach:
Below is the implementation of the above approach:
C++
// C++ implementation to find the uncommon
// characters of the two strings
#include <bits/stdc++.h>
using namespace std;
// size of the hash table
const int MAX_CHAR = 26;
// function to find the uncommon characters
// of the two strings
string UncommonChars(string str1, string str2)
{
// mark presence of each character as 0
// in the hash table 'present[]'
string ans="";
int present[MAX_CHAR];
for (int i=0; i<MAX_CHAR; i++)
present[i] = 0;
int l1 = str1.size();
int l2 = str2.size();
// for each character of str1, mark its
// presence as 1 in 'present[]'
for (int i=0; i<l1; i++)
present[str1[i] - 'a'] = 1;
// for each character of str2
for (int i=0; i<l2; i++)
{
// if a character of str2 is also present
// in str1, then mark its presence as -1
if (present[str2[i] - 'a'] == 1
|| present[str2[i] - 'a'] == -1)
present[str2[i] - 'a'] = -1;
// else mark its presence as 2
else
present[str2[i] - 'a'] = 2;
}
// print all the uncommon characters
for (int i=0; i<MAX_CHAR; i++)
if (present[i] == 1 || present[i] == 2 )
ans.push_back(char(i+'a'));
if(ans.size()==0)
{
return "-1";
}
return ans;
}
// Driver program to test above
int main()
{
string str1 = "characters";
string str2 = "alphabets";
cout<<UncommonChars(str1, str2);
return 0;
}
Java
public class GfG {
static final int MAX_CHAR = 26;
public static String uncommonChars(String str1, String str2) {
StringBuilder ans = new StringBuilder();
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) {
ans.append((char)(i + 'a'));
}
}
if (ans.length() == 0) {
return "-1";
}
return ans.toString();
}
public static void main(String[] args) {
String str1 = "characters";
String str2 = "alphabets";
System.out.println(uncommonChars(str1, str2));
}
}
Python
def uncommon_chars(str1, str2):
MAX_CHAR = 26
ans = ""
present = [0] * MAX_CHAR
for char in str1:
present[ord(char) - ord('a')] = 1
for char in str2:
if present[ord(char) - ord('a')] == 1 or present[ord(char) - ord('a')] == -1:
present[ord(char) - ord('a')] = -1
else:
present[ord(char) - ord('a')] = 2
for i in range(MAX_CHAR):
if present[i] == 1 or present[i] == 2:
ans += chr(i + ord('a'))
if len(ans) == 0:
return "-1"
return ans
if __name__ == "__main__":
str1 = "characters"
str2 = "alphabets"
print(uncommon_chars(str1, str2))
C#
using System;
public class UncommonCharacters {
static int MAX_CHAR = 26;
static string UncommonChars(string str1, string str2) {
string ans = "";
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)
{
ans += (char)(i + 'a');
}
}
if (ans.Length == 0)
{
return "-1";
}
return ans;
}
static void Main(string[] args) {
string str1 = "characters";
string str2 = "alphabets";
Console.WriteLine(UncommonChars(str1, str2));
}
}
JavaScript
function uncommonChars(str1, str2) {
const MAX_CHAR = 26;
let ans = "";
let present = new Array(MAX_CHAR).fill(0);
for (let i = 0; i < str1.length; i++) {
present[str1.charCodeAt(i) - 'a'.charCodeAt(0)] = 1;
}
for (let i = 0; i < str2.length; i++) {
if (present[str2.charCodeAt(i) - 'a'.charCodeAt(0)] == 1 || present[str2.charCodeAt(i) - 'a'.charCodeAt(0)] == -1) {
present[str2.charCodeAt(i) - 'a'.charCodeAt(0)] = -1;
} else {
present[str2.charCodeAt(i) - 'a'.charCodeAt(0)] = 2;
}
}
for (let i = 0; i < MAX_CHAR; i++) {
if (present[i] == 1 || present[i] == 2) {
ans += String.fromCharCode(i + 'a'.charCodeAt(0));
}
}
if (ans.length === 0) {
return "-1";
}
return ans;
}
let str1 = "characters";
let str2 = "alphabets";
console.log(uncommonChars(str1, str2));
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.