Find uncommon characters of the two strings

Last Updated : 3 Oct, 2026

Given two strings s1 and s2. Your task is to identify the characters that appear in either string but not in both (i.e., characters that are unique to one of the strings). Return the result as a sorted string.

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 Yourself
redirect icon

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

The idea is to use nested loops to check whether each character of s1 is present in s2, and each character of s2 is present in s1. Use a check[] array of size MAX_CHAR to handle duplicate characters and store each uncommon character only once.

  • For each character, check its presence in the other string and add it to res if it is not found and has not been added before.
  • Finally, sort res in ascending order and return it.
C++
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
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 res = "";

    // 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;
            res.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;
            res.push_back(s2[i]);
        }
    }

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

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

    cout << "\"" << uncommonChars(s1, s2) << "\"";
    return 0;
}
Java
import java.util.Arrays;

public 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)
    {
        // To store the answer
        String res = "";

        // To handle the case of duplicates, we use an array
        // 'check' to track visited characters
        boolean[] check = new boolean[MAX_CHAR];

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

            // Check if the character in s1 is present in s2
            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 the answer
            if (!found && !check[s1.charAt(i) - 'a']) {
                check[s1.charAt(i) - 'a'] = true;
                res += s1.charAt(i);
            }
        }

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

            // Check if the character in s2 is present in s1
            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 the answer
            if (!found && !check[s2.charAt(i) - 'a']) {
                check[s2.charAt(i) - 'a'] = true;
                res += s2.charAt(i);
            }
        }

        // Sort the result string
        char[] resArray = res.toCharArray();
        Arrays.sort(resArray);
        return new String(resArray);
    }

    public static void main(String[] args)
    {
        String s1 = "characters";
        String s2 = "alphabets";

        System.out.println("\"" + uncommonChars(s1, s2)
                           + "\"");
    }
}
Python
def uncommonChars(s1, s2):
    # To store the answer
    res = ""

    # To handle the case of duplicates, we use an array
    # 'check' to track visited characters
    check = [False] * 26

    # Check for characters in s1
    for i in range(len(s1)):
        # Keeping a flag variable
        found = False

        # Check if the character in s1 is present in s2
        for j in range(len(s2)):
            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 not found and not check[ord(s1[i]) - ord('a')]:
            check[ord(s1[i]) - ord('a')] = True
            res += s1[i]

    # Now check for characters in s2
    for i in range(len(s2)):
        # Keeping a flag variable
        found = False

        # Check if the character in s2 is present in s1
        for j in range(len(s1)):
            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 not found and not check[ord(s2[i]) - ord('a')]:
            check[ord(s2[i]) - ord('a')] = True
            res += s2[i]

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

if __name__ == '__main__':
    s1 = "characters"
    s2 = "alphabets"

    print("\"" + uncommonChars(s1, s2) + "\"")
C#
using System;
using System.Collections.Generic;
using System.Linq;

class GFG {
    const int MAX_CHAR = 26;

    // Function to find the uncommon characters of the two
    // strings
    static string uncommonChars(string s1, string s2)
    {
        // To store the answer
        string res = "";

        // To handle the case of duplicates, we use an array
        // 'check' to track visited characters
        bool[] check = new bool[MAX_CHAR];

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

            // Check if the character in s1 is present in s2
            for (int j = 0; j < s2.Length; 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;
                res += s1[i];
            }
        }

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

            // Check if the character in s2 is present in s1
            for (int j = 0; j < s1.Length; 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;
                res += s2[i];
            }
        }

        // Sort the result string
        char[] resArray = res.ToCharArray();
        Array.Sort(resArray);
        res = new string(resArray);
        return res;
    }

    static void Main(string[] args)
    {
        string s1 = "characters";
        string s2 = "alphabets";

        Console.WriteLine("\"" + uncommonChars(s1, s2)
                          + "\"");
    }
}
JavaScript
// Function to find the uncommon characters of the two
// strings
function uncommonChars(s1, s2)
{
    const MAX_CHAR = 26;

    // To store the answer
    let res = "";

    // To handle the case of duplicates, we use an array
    // 'check' to track visited characters
    let check = Array(MAX_CHAR).fill(false);

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

        // Check if the character in s1 is present in s2
        for (let j = 0; j < s2.length; 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].charCodeAt(0)
                      - "a".charCodeAt(0)]) {
            check[s1[i].charCodeAt(0) - "a".charCodeAt(0)]
                = true;
            res += s1[i];
        }
    }

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

        // Check if the character in s2 is present in s1
        for (let j = 0; j < s1.length; 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].charCodeAt(0)
                      - "a".charCodeAt(0)]) {
            check[s2[i].charCodeAt(0) - "a".charCodeAt(0)]
                = true;
            res += s2[i];
        }
    }

    // Sort the result string
    res = res.split("").sort().join("");
    return res;
}

// Driver Code
let s1 = "characters";
let s2 = "alphabets";
console.log(`\"${uncommonChars(s1, s2)}\"`);

Output
"bclpr"

[Expected Approach] Array Indexing - O(n + m) Time and O(MAX_CHAR) Space

The idea is to use an array present[] of size MAX_CHAR to store the status of each character. Mark characters of s1 as 1, then update the status while traversing s2 to identify characters present in both or only in s2.

  • Mark characters of s1 as 1; while traversing s2, mark common characters as -1 and new characters as 2.
  • Finally, traverse present[] and add characters with value 1 or 2 to res. Since the array is traversed from a to z, the result is already sorted.

Let us understand with an example:
Input: s1 = "characters", s2 = "alphabets"

  • First, traverse s1 and mark its characters as 1 in present[]: a, c, e, h, r, s, t.
  • Traverse s2. Common characters a, e, h, s, t are marked as -1, while new characters b, l, p are marked as 2.
  • Finally, traverse present[] and add characters having value 1 or 2 to res.
  • The uncommon characters are b, c, l, p, r.

Output: "bclpr".

C++
#include <iostream>
#include <string>
#include <vector>
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 res = "";

    // 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)
            res.push_back(char(i + 'a'));

    return res;
}

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

    cout << "\"" << uncommonChars(s1, s2) << "\"";
    return 0;
}
Java
import java.util.Arrays;

public 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)
    {

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

        // string to store the answer.
        StringBuilder res = new StringBuilder("");

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

        // for each character of s2
        for (int 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.charAt(i) - 'a'] == 1
                || present[s2.charAt(i) - 'a'] == -1)
                present[s2.charAt(i) - 'a'] = -1;

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

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

        return res.toString();
    }

    public static void main(String[] args)
    {
        String s1 = "characters";
        String s2 = "alphabets";

        System.out.println("\"" + uncommonChars(s1, s2)
                           + "\"");
    }
}
Python
# function to find the uncommon characters
# of the two strings
def uncommonChars(s1, s2):
    
    MAX_CHAR = 26
    
    # mark presence of each character as 0
    # in the hash table 'present[]'
    present = [0] * MAX_CHAR

    # string to store the answer.
    res = ""

    # for each character of s1, mark its
    # presence as 1 in 'present[]'
    for char in s1:
        present[ord(char) - ord('a')] = 1

    # for each character of s2
    for char in s2:
        # if a character of s2 is also present
        # in s1, then mark its presence as -1
        if present[ord(char) - ord('a')] == 1 or present[ord(char) - ord('a')] == -1:
            present[ord(char) - ord('a')] = -1
        # else mark its presence as 2
        else:
            present[ord(char) - ord('a')] = 2

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

    return res

if __name__ == '__main__':
    s1 = "characters"
    s2 = "alphabets"
    print("\"" + uncommonChars(s1, s2) + "\"")
C#
using System;

class GFG {
    const int MAX_CHAR = 26;

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

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

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

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

        // for each character of s2
        for (int 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[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)
                res += (char)(i + 'a');

        return res;
    }

    static void Main()
    {
        string s1 = "characters";
        string s2 = "alphabets";

        Console.WriteLine("\"" + uncommonChars(s1, s2)
                          + "\"");
    }
}
JavaScript
// function to find the uncommon characters
// of the two strings
function uncommonChars(s1, s2)
{
    const MAX_CHAR = 26;

    // mark presence of each character as 0
    // in the hash table 'present[]'
    const present = new Array(MAX_CHAR).fill(0);

    // string to store the answer.
    let res = "";

    // 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)
            res += String.fromCharCode(i
                                       + "a".charCodeAt(0));

    return res;
}

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

Output
"bclpr"

Note: MAX_CHAR represents the size of the character set. Since the input contains only lowercase English letters, MAX_CHAR is 26. If the input contains all ASCII characters, MAX_CHAR would be 256.

[Alternate Approach] Bit Manipulation - O(n + m) Time and O(1) Space

The idea is to use two variables that store the bitwise OR of the left shift of 1 with each character's ASCII code - 97, i.e. 0 for 'a', 1 for 'b', and so on.

For both strings, we get an integer after performing these bitwise operations. The bitwise XOR of these two integers gives the bit as 1 only at positions that denote uncommon characters because XOR of opposite bits is 1.

  • Traverse both strings and set the bit corresponding to each character.
  • Print the character values for the positions where the resulting bit is 1.

Let us understand with an example:
Input: s1 = "characters", s2 = "alphabets"

  • For s1 = "characters", the bits corresponding to a, c, e, h, r, s, t are set in a1.
  • For s2 = "alphabets", the bits corresponding to a, b, e, h, l, p, s, t are set in a2.
  • res = a1 ^ a2 keeps only the bits of characters that occur in one string but not both, giving b, c, l, p, r.
  • Traverse the 26 bits from a to z and add the characters whose bits are set.

Output: "bclpr".

C++
#include <iostream>
#include <string>
using namespace std;

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

    // Store characters of s1 and s2 using bits
    int a1 = 0, a2 = 0;

    // Set the bit corresponding to each character of s1
    for (int i = 0; i < s1.length(); i++)
    {
        int ch = s1[i] - 'a';
        a1 = a1 | (1 << ch);
    }

    // Set the bit corresponding to each character of s2
    for (int i = 0; i < s2.length(); i++)
    {
        int ch = s2[i] - 'a';
        a2 = a2 | (1 << ch);
    }

    // XOR leaves only uncommon characters
    int res = a1 ^ a2;

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

    // Check each of the 26 bits
    for (int i = 0; i < 26; i++)
    {
        if (res % 2 == 1)
            ans.push_back(char('a' + i));

        res = res / 2;
    }

    return ans;
}

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

    cout << "\"" << uncommonChars(s1, s2) << "\"";
    return 0;
}
Java
import java.util.Scanner;

// Function to find the uncommon characters
// of the two strings
public class GFG {
    public static String uncommonChars(String s1, String s2)
    {

        // Store characters of s1 and s2 using bits
        int a1 = 0, a2 = 0;

        // Set the bit corresponding to each character of s1
        for (int i = 0; i < s1.length(); i++) {
            int ch = s1.charAt(i) - 'a';
            a1 = a1 | (1 << ch);
        }

        // Set the bit corresponding to each character of s2
        for (int i = 0; i < s2.length(); i++) {
            int ch = s2.charAt(i) - 'a';
            a2 = a2 | (1 << ch);
        }

        // XOR leaves only uncommon characters
        int res = a1 ^ a2;

        // To store the result
        String ans = "";

        // Check each of the 26 bits
        for (int i = 0; i < 26; i++) {
            if (res % 2 == 1)
                ans += (char)('a' + i);

            res = res / 2;
        }

        return ans;
    }

    public static void main(String[] args)
    {
        String s1 = "characters";
        String s2 = "alphabets";

        System.out.println("\"" + uncommonChars(s1, s2)
                           + "\"");
    }
}
Python
# Function to find the uncommon characters
# of the two strings
def uncommonChars(s1, s2):

    # Store characters of s1 and s2 using bits
    a1 = 0
    a2 = 0

    # Set the bit corresponding to each character of s1
    for i in range(len(s1)):
        ch = ord(s1[i]) - ord('a')
        a1 = a1 | (1 << ch)

    # Set the bit corresponding to each character of s2
    for i in range(len(s2)):
        ch = ord(s2[i]) - ord('a')
        a2 = a2 | (1 << ch)

    # XOR leaves only uncommon characters
    res = a1 ^ a2

    # To store the result
    ans = ''

    # Check each of the 26 bits
    for i in range(26):
        if res % 2 == 1:
            ans += chr(ord('a') + i)

        res = res // 2

    return ans


if __name__ == "__main__":
    s1 = 'characters'
    s2 = 'alphabets'

    print(f'"{uncommonChars(s1, s2)}"')
C#
using System;
using System.Text;

class GFG {
    // Function to find the uncommon characters
    // of the two strings
    static string uncommonChars(string s1, string s2)
    {
        // Store characters of s1 and s2 using bits
        int a1 = 0, a2 = 0;

        // Set the bit corresponding to each character of s1
        for (int i = 0; i < s1.Length; i++) {
            int ch = s1[i] - 'a';
            a1 = a1 | (1 << ch);
        }

        // Set the bit corresponding to each character of s2
        for (int i = 0; i < s2.Length; i++) {
            int ch = s2[i] - 'a';
            a2 = a2 | (1 << ch);
        }

        // XOR leaves only uncommon characters
        int res = a1 ^ a2;

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

        // Check each of the 26 bits
        for (int i = 0; i < 26; i++) {
            if ((res & 1) == 1)
                ans += (char)('a' + i);

            res = res >> 1;
        }

        return ans;
    }

    static void Main()
    {
        string s1 = "characters";
        string s2 = "alphabets";

        Console.WriteLine("\"" + uncommonChars(s1, s2)
                          + "\"");
    }
}
JavaScript
function uncommonChars(s1, s2)
{
    // Store characters of s1 and s2 using bits
    let a1 = 0, a2 = 0;

    // Set the bit corresponding to each character of s1
    for (let i = 0; i < s1.length; i++) {
        let ch = s1.charCodeAt(i) - "a".charCodeAt(0);
        a1 = a1 | (1 << ch);
    }

    // Set the bit corresponding to each character of s2
    for (let i = 0; i < s2.length; i++) {
        let ch = s2.charCodeAt(i) - "a".charCodeAt(0);
        a2 = a2 | (1 << ch);
    }

    // XOR leaves only uncommon characters
    let res = a1 ^ a2;

    // To store the result
    let ans = "";

    // Check each of the 26 bits
    for (let i = 0; i < 26; i++) {
        if ((res & 1) === 1)
            ans += String.fromCharCode("a".charCodeAt(0)
                                       + i);

        res = res >> 1;
    }

    return ans;
}

// Driver Code
let s1 = "characters";
let s2 = "alphabets";
console.log("\"" + uncommonChars(s1, s2) + "\"");

Output
"bclpr"
Comment