Open In App

Longest Uncommon Subsequence

Improve
Improve
Like Article
Like
Save
Share
Report

Given two strings, find the length of longest uncommon subsequence of the two strings. The longest uncommon subsequence is defined as the longest subsequence of one of these strings which is not a subsequence of other strings. 

Examples: 

Input : "abcd", "abc"
Output : 4
The longest subsequence is 4 because "abcd"
is a subsequence of first string, but not
a subsequence of second string.
Input : "abc", "abc"
Output : 0
Both strings are same, so there is no
uncommon subsequence.

Brute Force: In general, the first thought some people may have is to generate all possible 2n subsequences of both the strings and store their frequency in a hashmap. Longest subsequence whose frequency is equal to 1 will be the required subsequence. 

Implementation:

C++




// CPP program to find longest uncommon
// subsequence using naive method
#include <iostream>
#include <unordered_map>
#include <vector>
using namespace std;
 
// function to calculate length of longest uncommon subsequence
int findLUSlength(string a, string b)
{
    /* creating an unordered map to map
       strings to their frequency*/
    unordered_map<string, int> map;
    vector<string> strArr;
    strArr.push_back(a);
    strArr.push_back(b);
 
    // traversing all elements of vector strArr
    for (string s : strArr)
    {
        /* Creating all possible subsequences, i.e 2^n*/
        for (int i = 0; i < (1 << s.length()); i++)
        {
            string t = "";
            for (int j = 0; j < s.length(); j++) {
 
                /* ((i>>j) & 1) determines which 
                   character goes into string t*/
                if (((i >> j) & 1) != 0) 
                    t += s[j];
            }
 
            /* If common subsequence is found,
               increment its frequency*/
            if (map.count(t))
                map[t]++;
            else
                map[t] = 1;
        }
    }
    int res = 0;
    for (auto a : map) // traversing the map
    {
         // if frequency equals 1  
        if (a.second == 1)
            res = max(res, (int)a.first.length());
    }
    return res;
}
int main()
{
    // Your C++ Code
    string a = "abcdabcd", b = "abcabc"; // input strings
    cout << findLUSlength(a, b);
    return 0;
}


Java




// Java program to find longest uncommon
// subsequence using naive method
import java.io.*;
import java.util.*;
  
class GfG{
      
// function to calculate length of
// longest uncommon subsequence
static int findLUSlength(String a, String b)
{
    // creating an unordered map to map
    // strings to their frequency
    HashMap<String, Integer> map= new HashMap<String, Integer>();
    Vector<String> strArr= new Vector<String>();
    strArr.add(a);
    strArr.add(b);
 
    // traversing all elements of vector strArr
    for (String s : strArr)
    {
        // Creating all possible subsequences, i.e 2^n
        for (int i = 0; i < (1 << s.length()); i++)
        {
            String t = "";
            for (int j = 0; j < s.length(); j++) {
 
                // ((i>>j) & 1) determines which
                // character goes into string t
                if (((i >> j) & 1) != 0)
                    t += s.charAt(j);
            }
 
            // If common subsequence is found,
            // increment its frequency
            if (map.containsKey(t))
                map.put(t,map.get(t)+1);
            else
                map.put(t,1);
        }
    }
    int res = 0;
    for (HashMap.Entry<String, Integer> entry : map.entrySet())
 
    // traversing the map
    {
        // if frequency equals 1
        if (entry.getValue() == 1)
            res = Math.max(res, entry.getKey().length());
    }
    return res;
}
 
    // Driver code
    public static void main (String[] args) {
 
    // input strings
    String a = "abcdabcd", b = "abcabc";
       System.out.println(findLUSlength(a, b));
    }
}
 
// This code is contributed by Gitanjali.


Python3




# Python3 program to find longest uncommon
# subsequence using naive method
 
# function to calculate length of
# longest uncommon subsequence
def findLUSlength(a, b):
 
    ''' creating an unordered map to map
    strings to their frequency'''
    map = dict()
    strArr = []
    strArr.append(a)
    strArr.append(b)
 
    # traversing all elements of vector strArr
    for s in strArr:
         
        ''' Creating all possible subsequences, i.e 2^n'''
        for i in range(1 << len(s)):
            t = ""
            for j in range(len(s)):
 
                ''' ((i>>j) & 1) determines which
                character goes into t'''
                if (((i >> j) & 1) != 0):
                    t += s[j]
 
            # If common subsequence is found,
            # increment its frequency
            if (t in map.keys()):
                map[t] += 1;
            else:
                map[t] = 1
 
    res = 0
    for a in map: # traversing the map
                  # if frequency equals 1
        if (map[a] == 1):
            res = max(res, len(a))
 
    return res
 
# Driver Code
a = "abcdabcd"
b = "abcabc" # input strings
print(findLUSlength(a, b))
 
# This code is contributed by Mohit Kumar


C#




// C# program to find longest
// uncommon subsequence using
// naive method
using System;
using System.Collections.Generic;
 
class GFG
{    
    // function to calculate
    // length of longest
    // uncommon subsequence
    static int findLUSlength(string a,
                             string b)
    {
        // creating an unordered
        // map to map strings to
        // their frequency
        Dictionary<string, int> map =
                   new Dictionary<string, int>();
        List<string> strArr =
                 new List<string>();
        strArr.Add(a);
        strArr.Add(b);
     
        // traversing all elements
        // of vector strArr
        foreach (string s in strArr)
        {
            // Creating all possible
            // subsequences, i.e 2^n
            for (int i = 0;
                     i < (1 << s.Length); i++)
            {
                string t = "";
                for (int j = 0;
                         j < s.Length; j++)
                {
     
                    // ((i>>j) & 1) determines
                    // which character goes
                    // into string t
                    if (((i >> j) & 1) != 0)
                        t += s[j];
                }
     
                // If common subsequence
                // is found, increment
                // its frequency
                if (map.ContainsKey(t))
                {
                    int value = map[t] + 1;
                    map.Remove(t);
                    map.Add(t, value);
                }
                else
                    map.Add(t, 1);
            }
        }
        int res = 0;
        foreach (KeyValuePair<string, int>
                             entry in map)
        // traversing the map
        {
            // if frequency equals 1
            if (entry.Value == 1)
                res = Math.Max(res,
                           entry.Key.Length);
        }
        return res;
    }
     
    // Driver code
    static void Main ()
    {
         
        // input strings
        string a = "abcdabcd",
               b = "abcabc";
         
        Console.Write(findLUSlength(a, b));
    }
}
 
// This code is contributed by
// Manish Shaw(manishshaw1)


Javascript




<script>
 
// JavaScript program to find longest uncommon
// subsequence using naive method
 
    // function to calculate length of
// longest uncommon subsequence
    function findLUSlength(a,b)
    {
        // creating an unordered map to map
    // strings to their frequency
    let map= new Map();
    let strArr= [];
    strArr.push(a);
    strArr.push(b);
   
    // traversing all elements of vector strArr
    for (let s=0; s<strArr.length;s++)
    {
        // Creating all possible subsequences, i.e 2^n
        for (let i = 0; i < (1 << strArr[s].length); i++)
        {
            let t = "";
            for (let j = 0; j < strArr[s].length; j++) {
   
                // ((i>>j) & 1) determines which
                // character goes into string t
                if (((i >> j) & 1) != 0)
                     
                    t += strArr[s][j];
                     
            }
   
            // If common subsequence is found,
            // increment its frequency
            if (map.has(t))
                map.set(t,map.get(t)+1);
            else
                map.set(t,1);
        }
    }
    let res = 0;
    for (let [key, value] of map.entries())
   
    // traversing the map
    {
        // if frequency equals 1
        if (value == 1)
            res = Math.max(res, key.length);
    }
    return res;
    }
     
    // Driver code
     
    // input strings
    let a = "abcdabcd", b = "abcabc";
    document.write(findLUSlength(a, b));
     
 
// This code is contributed by unknown2108
 
</script>


Output

8





Complexities:

  • Time complexity: O(2x + 2y), where x and y are the lengths of two strings.
  • Auxiliary Space : O(2x + 2y).

Efficient Algorithm: 

If we analyze the problem carefully, it would seem much easier than it looks. All the three possible cases are as described below; 

  1. If both the strings are identical, for example: “ac” and “ac”, it is obvious that no subsequence will be uncommon. Hence, return 0.
  2. If length(a) = length(b) and a ? b, for example: “abcdef” and “defghi”, out of these two strings one string will never be a subsequence of other string. 
    Hence, return length(a) or length(b).
  3. If length(a) > length(b), for example: “abcdabcd” and “abcabc”, in this case we can consider bigger string as a required subsequence because bigger string can not be a subsequence of smaller string. Hence, return max(length(a), length(b)).

Implementation:

C++




// CPP Program to find longest uncommon
// subsequence.
#include <iostream>
using namespace std;
 
// function to calculate length of longest
// uncommon subsequence
int findLUSlength(string a, string b)
{
    // Case 1: If strings are equal
    if (!a.compare(b))
        return 0;
 
     // for case 2 and case 3
    return max(a.length(), b.length());
}
 
// Driver code
int main()
{
    string a = "abcdabcd", b = "abcabc";
    cout << findLUSlength(a, b);
    return 0;
}


Java




// Java program to find longest uncommon
// subsequence using naive method
 
import java.io.*;
import java.util.*;
  
class GfG{
      
// function to calculate length of longest
// uncommon subsequence
static int findLUSlength(String a, String b)
{
    // Case 1: If strings are equal
    if (a.equals(b)==true)
        return 0;
  
     // for case 2 and case 3
    return Math.max(a.length(), b.length());
}
    // Driver code
    public static void main (String[] args) {
 
    // input strings
    String a = "abcdabcd", b = "abcabc";
       System.out.println(findLUSlength(a, b));
    }
}
 
// This code is contributed by Gitanjali.


Python3




# Python program to find
# longest uncommon
# subsequence using naive method
 
import math
 
# function to calculate
# length of longest
# uncommon subsequence
def findLUSlength( a, b):
 
    # Case 1: If strings are equal
    if (a==b) :
        return 0
  
     # for case 2 and case 3
    return max(len(a), len(b))
 
# Driver code
 
#input strings
a = "abcdabcd"
b = "abcabc"
print (findLUSlength(a, b))
 
# This code is contributed by Gitanjali.


C#




// C# program to find longest uncommon
// subsequence using naive method.
using System;
 
class GfG {
     
    // function to calculate length
    // of longest uncommon subsequence
    static int findLUSlength(String a, String b)
    {
         
        // Case 1: If strings are equal
        if (a.Equals(b)==true)
            return 0;
     
        // for case 2 and case 3
        return Math.Max(a.Length, b.Length);
    }
     
    // Driver code
    public static void Main ()
    {
 
        // input strings
        String a = "abcdabcd", b = "abcabc";
        Console.Write(findLUSlength(a, b));
    }
}
 
// This code is contributed by nitin mittal.


Javascript




<script>
 
// JavaScript Program to find longest uncommon
// subsequence.
 
// function to calculate length of longest
// uncommon subsequence
function findLUSlength(a, b)
{
    // Case 1: If strings are equal
    if (a===b)
        return 0;
 
     // for case 2 and case 3
    return Math.max(a.length, b.length);
}
 
// Driver code
var a = "abcdabcd", b = "abcabc";
document.write( findLUSlength(a, b));
 
</script>


PHP




<?php
// PHP Program to find longest
// uncommon subsequence.
 
// function to calculate length
// of longest uncommon subsequence
function findLUSlength($a, $b)
{
    // Case 1: If strings
    // are equal
    if (!strcmp($a, $b))
        return 0;
 
    // for case 2
    // and case 3
    return max(strlen($a),
               strlen($b));
}
 
// Driver code
$a = "abcdabcd";
$b = "abcabc";
echo (findLUSlength($a, $b));
 
// This code is contributed by
// Manish Shaw(manishshaw1)
?>


Output

8





Complexity Analysis: 

  • Time complexity: O(min(x, y)), where x and y are the lengths of two strings.
  • Auxiliary Space: O(1).

Approach#3: Using set()

Using set to compare the characters of the two strings. If the sets are equal, then there is no uncommon subsequence, and -1 is returned. Otherwise, the length of the longer string is returned.

Algorithm

1. Create a set of both strings.
2. Check if the sets are equal.
3. If they are equal, then return -1.
4. If they are not equal, then return the length of the longer string.

C++




#include <bits/stdc++.h>
using namespace std;
 
// Helper function to check if two sets are equal
bool areSetsEqual(unordered_set<char>& set1, unordered_set<char>& set2) {
    if (set1.size() != set2.size()) {
        return false;
    }
    for (char item : set1) {
        if (set2.find(item) == set2.end()) {
            return false;
        }
    }
    return true;
}
 
int find_lus_length(string s1,string s2) {
    // Create sets of characters in s1 and s2
    unordered_set<char> set1(s1.begin(), s1.end());
    unordered_set<char> set2(s2.begin(), s2.end());
    // If the sets are equal, return -1
    if (areSetsEqual(set1, set2)) {
        return -1;
    } else {
        // Otherwise, return the maximum length of s1 and s2
        return max(s1.length(), s2.length());
    }
}
//Driver Code
int main() {
    string s1 = "abcdabcd";
    string s2 = "abcabc";
    cout << find_lus_length(s1, s2) << endl;
    return 0;
}


Java




import java.util.HashSet;
 
public class Main {
 
    // Helper function to check if two sets are equal
    public static boolean areSetsEqual(HashSet<Character> set1, HashSet<Character> set2) {
        if (set1.size() != set2.size()) {
            return false;
        }
        for (char item : set1) {
            if (!set2.contains(item)) {
                return false;
            }
        }
        return true;
    }
 
    public static int findLUSLength(String s1, String s2) {
        // Create sets of characters in s1 and s2
        HashSet<Character> set1 = new HashSet<>();
        HashSet<Character> set2 = new HashSet<>();
        for (char c : s1.toCharArray()) {
            set1.add(c);
        }
        for (char c : s2.toCharArray()) {
            set2.add(c);
        }
         
        // If the sets are equal, return -1
        if (areSetsEqual(set1, set2)) {
            return -1;
        } else {
            // Otherwise, return the maximum length of s1 and s2
            return Math.max(s1.length(), s2.length());
        }
    }
 
    public static void main(String[] args) {
        String s1 = "abcdabcd";
        String s2 = "abcabc";
        System.out.println(findLUSLength(s1, s2));
    }
}


Python3




def find_lus_length(s1, s2):
    set1 = set(s1)
    set2 = set(s2)
    if set1 == set2:
        return -1
    else:
        return max(len(s1), len(s2))
s1 = "abcdabcd"
s2 = "abcabc"
print(find_lus_length(s1, s2))


C#




using System;
using System.Collections.Generic;
 
class GFG {
    // Helper function to check if two sets are equal
    static bool areSetsEqual(HashSet<char> set1,
                             HashSet<char> set2)
    {
        if (set1.Count != set2.Count) {
            return false;
        }
        foreach(char item in set1)
        {
            if (!set2.Contains(item)) {
                return false;
            }
        }
        return true;
    }
 
    static int find_lus_length(string s1, string s2)
    {
        // Create sets of characters in s1 and s2
        HashSet<char> set1 = new HashSet<char>(s1);
        HashSet<char> set2 = new HashSet<char>(s2);
 
        // If the sets are equal, return -1
        if (areSetsEqual(set1, set2)) {
            return -1;
        }
        else {
            // Otherwise, return the maximum length of s1
            // and s2
            return Math.Max(s1.Length, s2.Length);
        }
    }
 
    // Driver Code
    static void Main(string[] args)
    {
        string s1 = "abcdabcd";
        string s2 = "abcabc";
        Console.WriteLine(find_lus_length(s1, s2));
    }
}


Javascript




function find_lus_length(s1, s2) {
    // Create sets of characters in s1 and s2
    let set1 = new Set(s1);
    let set2 = new Set(s2);
 
    // If the sets are equal, return -1
    if (areSetsEqual(set1, set2)) {
        return -1;
    } else {
        // Otherwise, return the maximum length of s1 and s2
        return Math.max(s1.length, s2.length);
    }
}
 
// Helper function to check if two sets are equal
function areSetsEqual(set1, set2) {
    if (set1.size !== set2.size) {
        return false;
    }
    for (let item of set1) {
        if (!set2.has(item)) {
            return false;
        }
    }
    return true;
}
 
let s1 = "abcdabcd";
let s2 = "abcabc";
console.log(find_lus_length(s1, s2));


Output

8





Time Complexity: O(n) since it has to loop through the strings once to create the sets.

Auxiliary Space: O(n) since sets are used to store the characters of the strings.



Last Updated : 16 Oct, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads