Find uncommon characters of the two strings (original) (raw)

Last Updated : 26 Dec, 2024

Given two strings **s1 and **s2, the task is to **find the **uncommon **characters in **both strings. An uncommon character means that the **character is **present in only **one string or in **another string but **not in **both. The strings contain only **lowercase characters and can have **duplicates.

**Note: Output the uncommon characters in **sorted order.

**Examples:

**Input: s1 = "geeksforgeeks", s2 = "geeksquiz"
**Output: "fioqruz"
**Explanation: The characters 'f', 'i', 'o', 'q', 'r', 'u', and 'z' are present in either s1 or s2, but not in both.

**Input: s1 = "characters", s2 = "alphabets"
**Output: "bclpr"
**Explanation: The characters 'b', 'c', 'l', 'p', and 'r' are present in either s1 or s2, but not in both.

**Input: s1 = "rome", s2 = "more"
**Output: ""
**Explanation: Both strings contain the same characters, so there are no unique characters. The output is an empty string.

Try It Yourselfredirect icon

Table of Content

[Naive Approach] Using Two Nested Loops - O(n*m) Time and O(MAX_CHAR) Space

The idea is to use nested loops: for each character in string s1, **check whether it is present in string s2 or not. Likewise, for each character in **string s2, **check whether it is present in string s1 or not. Create an array **check[] of **size MAX_CHAR (where MAX_CHAR is set to 26 for lowercase English letters) to flag the already used characters. Store the **uncommon characters in a character array or string. Finally, **sort the characters in ascending order and print the result.

C++ `

// C++ implementation to find the uncommon // characters of the two strings #include <bits/stdc++.h> using namespace std;

const int MAX_CHAR = 26;

// Function to find the uncommon characters of the two strings string uncommonChars(string &s1, string &s2) {

// To store the answer
string ans = "";

// To handle the case of duplicates, we use an array 
// 'check' to track visited characters
vector<bool> check(MAX_CHAR, false);

// Check for characters in s1
for (int i = 0; i < s1.size(); i++) {
  
    // Keeping a flag variable
    bool found = false;

    // Check if the character in s1 is present in s2
    for (int j = 0; j < s2.size(); j++) {
        if (s1[i] == s2[j]) {
            found = true;
            break;
        }
    }

    // If character is not found in s2 and not already 
      // used, add it to the answer
    if (!found && !check[s1[i] - 'a']) {
        check[s1[i] - 'a'] = true;
        ans.push_back(s1[i]);
    }
}

// Now check for characters in s2
for (int i = 0; i < s2.size(); i++) {
  
    // Keeping a flag variable
    bool found = false;

    // Check if the character in s2 is present in s1
    for (int j = 0; j < s1.size(); j++) {
        if (s2[i] == s1[j]) {
            found = true;
            break;
        }
    }

    // If character is not found in s1 and not already
      // used, add it to the answer
    if (!found && !check[s2[i] - 'a']) {
        check[s2[i] - 'a'] = true;
        ans.push_back(s2[i]);
    }
}

// Sort the result string
sort(ans.begin(), ans.end());
return ans;

}

int main() { string s1 = "characters"; string s2 = "alphabets";

cout << uncommonChars(s1, s2);
return 0;

}

Java

// Java implementation to find the uncommon // characters of the two strings import java.util.Arrays;

class GfG {

static final int MAX_CHAR = 26;

// Function to find the uncommon characters of the two
// strings
static String uncommonChars(String s1, String s2) {
  
    StringBuilder ans = new StringBuilder();

    // To handle the case of duplicates
    boolean[] check = new boolean[MAX_CHAR];

    // Check first for s1
    for (int i = 0; i < s1.length(); i++) {
        boolean found = false;

        for (int j = 0; j < s2.length(); j++) {
            if (s1.charAt(i) == s2.charAt(j)) {
                found = true;
                break;
            }
        }

        // If character is not found in s2 and not
        // already used, add it to ans
        if (!found && !check[s1.charAt(i) - 'a']) {
            check[s1.charAt(i) - 'a'] = true;
            ans.append(s1.charAt(i));
        }
    }

    // Now check for s2
    for (int i = 0; i < s2.length(); i++) {
        boolean found = false;

        for (int j = 0; j < s1.length(); j++) {
            if (s2.charAt(i) == s1.charAt(j)) {
                found = true;
                break;
            }
        }

        // If character is not found in s1 and not
        // already used, add it to ans
        if (!found && !check[s2.charAt(i) - 'a']) {
            check[s2.charAt(i) - 'a'] = true;
            ans.append(s2.charAt(i));
        }
    }

    // Sort the answer string
    char[] ansArray = ans.toString().toCharArray();
    Arrays.sort(ansArray);
    return new String(ansArray);
}

public static void main(String[] args) {
    String s1 = "characters";
    String s2 = "alphabets";
    System.out.println(uncommonChars(s1, s2));
}

}

Python

Python implementation to find the uncommon

characters of the two strings

MAX_CHAR = 26

def uncommonChars(s1, s2): ans = ""

# to handle the case of duplicates
check = [False] * MAX_CHAR

# check first for s1
for i in range(len(s1)):
    found = False

    for j in range(len(s2)):
        if s1[i] == s2[j]:
            found = True
            break

    if not found and not check[ord(s1[i]) - ord('a')]:
        check[ord(s1[i]) - ord('a')] = True
        ans += s1[i]

# now check for s2
for i in range(len(s2)):
    found = False

    for j in range(len(s1)):
        if s2[i] == s1[j]:
            found = True
            break

    if not found and not check[ord(s2[i]) - ord('a')]:
        check[ord(s2[i]) - ord('a')] = True
        ans += s2[i]

# Sort the result string
ans = ''.join(sorted(ans))
return ans

if name == "main": s1 = "characters" s2 = "alphabets" print(uncommonChars(s1, s2))

C#

// C# implementation to find the uncommon // characters of the two strings using System; using System.Text;

class GfG {

const int MAX_CHAR = 26;

// Function to find the uncommon characters of the two
// strings
static string uncommonChars(string s1, string s2) {
    StringBuilder ans = new StringBuilder("");

    // to handle the case of duplicates
    bool[] check = new bool[MAX_CHAR];

    // Check first for s1
    for (int i = 0; i < s1.Length; i++) {
        bool found = false;

        for (int j = 0; j < s2.Length; j++) {
            if (s1[i] == s2[j]) {
                found = true;
                break;
            }
        }

        if (!found && !check[s1[i] - 'a']) {
            check[s1[i] - 'a'] = true;
            ans.Append(s1[i]);
        }
    }

    // Now check for s2
    for (int i = 0; i < s2.Length; i++) {
        bool found = false;

        for (int j = 0; j < s1.Length; j++) {
            if (s2[i] == s1[j]) {
                found = true;
                break;
            }
        }

        if (!found && !check[s2[i] - 'a']) {
            check[s2[i] - 'a'] = true;
            ans.Append(s2[i]);
        }
    }

    // Sort the answer
    char[] ansArray = ans.ToString().ToCharArray();
    Array.Sort(ansArray);
    return new string(ansArray);
}

static void Main(string[] args) {
    string s1 = "characters";
    string s2 = "alphabets";
    Console.WriteLine(uncommonChars(s1, s2));
}

}

JavaScript

// Javascript implementation to find the uncommon // characters of the two strings

function uncommonChars(s1, s2) { let ans = ""; const MAX_CHAR = 26;

// to handle the case of duplicates
let check = Array(MAX_CHAR).fill(false);

// check first for s1
for (let i = 0; i < s1.length; i++) {
    let found = false;

    for (let j = 0; j < s2.length; j++) {
        if (s1[i] === s2[j]) {
            found = true;
            break;
        }
    }

    if (!found && !check[s1.charCodeAt(i) - 'a'.charCodeAt(0)]) {
        check[s1.charCodeAt(i) - 'a'.charCodeAt(0)] = true;
        ans = ans.concat(s1[i]);
    }
}

// now check for s2
for (let i = 0; i < s2.length; i++) {
    let found = false;

    for (let j = 0; j < s1.length; j++) {
        if (s2[i] === s1[j]) {
            found = true;
            break;
        }
    }

    if (!found && !check[s2.charCodeAt(i) - 'a'.charCodeAt(0)]) {
        check[s2.charCodeAt(i) - 'a'.charCodeAt(0)] = true;
        ans = ans.concat(s2[i]);
    }
}

// sort the answer
ans = ans.split('').sort().join('');
return ans;

}

//driver code let s1 = "characters"; let s2 = "alphabets"; console.log(uncommonChars(s1, s2));

`

[Better Approach] Using Hashing - O(n + m) Time and O(MAX_CHAR) Space

The idea is to use a hash table , present[], of size **MAX_CHAR (set to 26 for the lowercase English alphabet), to store the characters of each string. First, iterate through the **string s1 and mark each character in the present[] array with the value 1. Then, iterate through the string s2, and update the **present[] array: mark characters already seen in s1 with the value -1 and mark new characters in s2 with the value 2. Finally, collect all characters marked as unique (i.e., those with value 1 or 2), and return them in **sorted order.

Note the **MAX_CHAR is alphabet size of input characters which is typically a constant. If we have only lower case characters, then MAX_CHAR is 26 only. If we consider all ASCII characters, then MAX_CHAR is 256.

C++ `

// C++ implementation to find the uncommon // characters of the two strings #include <bits/stdc++.h> using namespace std;

const int MAX_CHAR = 26;

// function to find the uncommon characters // of the two strings string uncommonChars(string &s1, string &s2) {

// mark presence of each character as 0
// in the hash table 'present[]'
vector<int> present(MAX_CHAR, 0);

// string to store the answer.
string ans = "";

// for each character of s1, mark its
// presence as 1 in 'present[]'
for (int i = 0; i < s1.size(); i++)
    present[s1[i] - 'a'] = 1;

// for each character of s2
for (int i = 0; i < s2.size(); i++) {

    // if a character of s2 is also present
    // in s1, then mark its presence as -1
    if (present[s2[i] - 'a'] == 1 || present[s2[i] - 'a'] == -1)
        present[s2[i] - 'a'] = -1;

    // else mark its presence as 2
    else
        present[s2[i] - 'a'] = 2;
}

// store all the uncommon characters
for (int i = 0; i < 26; i++)
    if (present[i] == 1 || present[i] == 2)
        ans.push_back(char(i + 'a'));

return ans;

}

int main() { string s1 = "characters"; string s2 = "alphabets"; cout << uncommonChars(s1, s2); return 0; }

Java

// Java implementation to find the uncommon // characters of the two strings import java.util.Arrays;

class GfG {

static final int MAX_CHAR = 26;
static String uncommonChars(String s1, String s2) {
    StringBuilder ans = new StringBuilder();

    // mark presence of each character as 0
    // in the hash table 'present[]'
    int[] present = new int[MAX_CHAR];

    for (int i = 0; i < 26; i++) {
        present[i] = 0;
    }

    // store each character of s1
    for (int i = 0; i < s1.length(); i++) {
        present[s1.charAt(i) - 'a'] = 1;
    }

    // check for each character of s2
    for (int i = 0; i < s2.length(); i++) {
        if (present[s2.charAt(i) - 'a'] == 1
            || present[s2.charAt(i) - 'a'] == -1) {
            present[s2.charAt(i) - 'a'] = -1;
        }
        else {
            present[s2.charAt(i) - 'a'] = 2;
        }
    }

    for (int i = 0; i < 26; i++) {
        if (present[i] == 1 || present[i] == 2) {
            ans.append((char)(i + 'a'));
        }
    }
    return ans.toString();
}

public static void main(String[] args) {
    String s1 = "characters";
    String s2 = "alphabets";
    System.out.println(uncommonChars(s1, s2));
}

}

Python

Python implementation to find the uncommon

characters of the two strings

MAX_CHAR = 26 def uncommonChars(s1, s2): ans = ""

# Mark presence of each character as 0 in the
# hash table 'present[]'
present = [0] * MAX_CHAR

# Store characters in s1
for char in s1:
    present[ord(char) - ord('a')] = 1

# Check for each character of s2
for char in s2:
    index = ord(char) - ord('a')
    if present[index] == 1:
        present[index] = -1
    elif present[index] == 0:
        present[index] = 2

# Collect the uncommon characters
for i in range(MAX_CHAR):
    if present[i] == 1 or present[i] == 2:
        ans += chr(i + ord('a'))

return ans

if name == "main": s1 = "characters" s2 = "alphabets" print(uncommonChars(s1, s2))

C#

// C# implementation to find the uncommon // characters of the two strings using System; using System.Text;

class GfG {

  static int MAX_CHAR = 26;

static string uncommonChars(string s1, string s2) {
       StringBuilder ans = new StringBuilder("");
      
      // create hashtable of size 26
      // and fill elements with 0
    int[] present = new int[MAX_CHAR];
    for (int i = 0; i < 26; i++) {
        present[i] = 0;
    }

      // store elements of s1
    for (int i = 0; i < s1.Length; i++) {
        present[s1[i] - 'a'] = 1;
    }
    
      // check for s2;
    for (int i = 0; i < s2.Length; i++) {
        if (present[s2[i] - 'a'] == 1 || 
            present[s2[i] - 'a'] == -1) {
            present[s2[i] - 'a'] = -1;
        }
        else {
            present[s2[i] - 'a'] = 2;
        }
    }

      // store the results.
    for (int i = 0; i < 26; i++) {
        if (present[i] == 1 || present[i] == 2) {
            ans.Append((char)(i + 'a'));
        }
    }
      char[] ansArray = ans.ToString().ToCharArray();
    Array.Sort(ansArray);
    return new string(ansArray);
}

static void Main(string[] args) {
    string s1 = "characters";
    string s2 = "alphabets";
    Console.WriteLine(uncommonChars(s1, s2));
}

}

JavaScript

// JavaScript function to find the uncommon characters // of two strings function uncommonChars(s1, s2) {

const MAX_CHAR = 26;
let present = new Array(MAX_CHAR).fill(0);
let ans = "";

// For each character of s1, mark its
// presence as 1 in 'present[]'
for (let i = 0; i < s1.length; i++) {
    present[s1.charCodeAt(i) - "a".charCodeAt(0)] = 1;
}

// For each character of s2
for (let i = 0; i < s2.length; i++) {

    // If a character of s2 is also present
    // in s1, then mark its presence as -1
    if (present[s2.charCodeAt(i) - "a".charCodeAt(0)]
            === 1
        || present[s2.charCodeAt(i) - "a".charCodeAt(0)]
               === -1) {
        present[s2.charCodeAt(i) - "a".charCodeAt(0)]
            = -1;
    }
    
    // Else mark its presence as 2
    else {
        present[s2.charCodeAt(i) - "a".charCodeAt(0)]
            = 2;
    }
}

// Store all the uncommon characters
for (let i = 0; i < 26; i++) {
    if (present[i] === 1 || present[i] === 2) {
        ans += String.fromCharCode(i
                                   + "a".charCodeAt(0));
    }
}

return ans;

}

// Driver code const s1 = "characters"; const s2 = "alphabets"; console.log(uncommonChars(s1, s2));

`

[Expected Approach] Using Bit Manipulation - O(n) Time and O(1) Space

The approach uses 2 variables that store the bit-wise OR of the **left shift of 1 with each character’s ASCII code. For both the strings, we get an integer after performing these bit-wise operations. Now the XOR of these two integers will give the binary bit as 1 at only those positions that denote uncommon characters. Print the character values for those positions. Please refer to Find uncommon characters of the two strings using Bit Manipulation for implementation.