Any Common Subsequence

Last Updated : 24 May, 2026

Given two strings s1 and s2. Check whether they contain any common subsequence (non empty) or not.

Examples:

Input: s1 = "ABEF", s2 = "CADE"
Output: true
Explanation: Subsequence "AE" occurs in both the strings.

Input: s1 = "ABCD", s2 = "EFGH"
Output: false
Explanation: There's no common subsequence in both the strings.

[Naive Approach] Generate All Subsequences - O(2^|s1| + 2^|s2|) Time O(2^|s1|) Space

  • Generate all possible non-empty subsequences of the first string using recursion and store them in a hash set for quick lookup.
  • Generate all subsequences of the second string and check whether any of them already exists in the hash set.
  • If a matching subsequence is found, it means both strings contain a common subsequence, so return true.
C++
#include <bits/stdc++.h>
using namespace std;

// Generate all subsequences
void generateSubseq(string &s, int idx, string curr, unordered_set<string> &st)
{

    // Store non-empty subsequence
    if (!curr.empty())
        st.insert(curr);

    if (idx == s.length())
        return;

    for (int i = idx; i < s.length(); i++)
    {
        generateSubseq(s, i + 1, curr + s[i], st);
    }
}

// Check subsequences of second string
bool checkSubseq(string &s, int idx, string curr, unordered_set<string> &st)
{

    if (!curr.empty() && st.find(curr) != st.end())
        return true;

    if (idx == s.length())
        return false;

    for (int i = idx; i < s.length(); i++)
    {

        if (checkSubseq(s, i + 1, curr + s[i], st))
            return true;
    }

    return false;
}

bool commonSubseq(string &s1, string &s2)
{

    unordered_set<string> st;

    // Generate subsequences of first string
    generateSubseq(s1, 0, "", st);

    // Check subsequences of second string
    return checkSubseq(s2, 0, "", st);
}

// Driver Code
int main()
{

    string s1 = "ABEF";
    string s2 = "CADE";

    if (commonSubseq(s1, s2))
        cout << "true";
    else
        cout << "false";

    return 0;
}
Java
import java.util.HashSet;
import java.util.Set;

public class GfG {

    // Generate all subsequences
    static void generateSubseq(String s, int idx, String curr, Set<String> st) {

        // Store non-empty subsequence
        if (!curr.isEmpty())
            st.add(curr);

        if (idx == s.length())
            return;

        for (int i = idx; i < s.length(); i++)
            generateSubseq(s, i + 1, curr + s.charAt(i), st);
    }

    // Check subsequences of second string
    static boolean checkSubseq(String s, int idx, String curr, Set<String> st) {

        if (!curr.isEmpty() && st.contains(curr))
            return true;

        if (idx == s.length())
            return false;

        for (int i = idx; i < s.length(); i++)
            if (checkSubseq(s, i + 1, curr + s.charAt(i), st))
                return true;

        return false;
    }

    static boolean commonSubseq(String s1, String s2) {

        Set<String> st = new HashSet<>();

        // Generate subsequences of first string
        generateSubseq(s1, 0, "", st);

        // Check subsequences of second string
        return checkSubseq(s2, 0, "", st);
    }

    public static void main(String[] args) {

        String s1 = "ABEF";
        String s2 = "CADE";

        if (commonSubseq(s1, s2))
            System.out.println("true");
        else
            System.out.println("false");
    }
}
Python
from typing import Set

# Generate all subsequences
def generateSubseq(s: str, idx: int, curr: str, st: Set[str]) -> None:

    # Store non-empty subsequence
    if curr:
        st.add(curr)

    if idx == len(s):
        return

    for i in range(idx, len(s)):
        generateSubseq(s, i + 1, curr + s[i], st)

# Check subsequences of second string
def checkSubseq(s: str, idx: int, curr: str, st: Set[str]) -> bool:

    if curr and curr in st:
        return True

    if idx == len(s):
        return False

    for i in range(idx, len(s)):
        if checkSubseq(s, i + 1, curr + s[i], st):
            return True

    return False

def commonSubseq(s1: str, s2: str) -> bool:

    st: Set[str] = set()

    # Generate subsequences of first string
    generateSubseq(s1, 0, "", st)

    # Check subsequences of second string
    return checkSubseq(s2, 0, "", st)

# Driver Code
if __name__ == "__main__":

    s1 = "ABEF"
    s2 = "CADE"

    if commonSubseq(s1, s2):
        print("true")
    else:
        print("false")
C#
using System;
using System.Collections.Generic;

class GfG
{
    // Generate all subsequences
    static void generateSubseq(string s, int idx, string curr, HashSet<string> st)
    {
        // Store non-empty subsequence
        if (!string.IsNullOrEmpty(curr))
            st.Add(curr);

        if (idx == s.Length)
            return;

        for (int i = idx; i < s.Length; i++)
        {
            generateSubseq(s, i + 1, curr + s[i], st);
        }
    }

    // Check subsequences of second string
    static bool checkSubseq(string s, int idx, string curr, HashSet<string> st)
    {
        if (!string.IsNullOrEmpty(curr) && st.Contains(curr))
            return true;

        if (idx == s.Length)
            return false;

        for (int i = idx; i < s.Length; i++)
        {
            if (checkSubseq(s, i + 1, curr + s[i], st))
                return true;
        }

        return false;
    }

    static bool commonSubseq(string s1, string s2)
    {
        HashSet<string> st = new HashSet<string>();

        // Generate subsequences of first string
        generateSubseq(s1, 0, "", st);

        // Check subsequences of second string
        return checkSubseq(s2, 0, "", st);
    }

    // Driver Code
    static void Main()
    {
        string s1 = "ABEF";
        string s2 = "CADE";

        if (commonSubseq(s1, s2))
            Console.WriteLine("true");
        else
            Console.WriteLine("false");
    }
}
JavaScript
function generateSubseq(s, idx, curr, st) {
    // Store non-empty subsequence
    if (curr.length > 0) {
        st.add(curr);
    }

    if (idx === s.length) {
        return;
    }

    for (let i = idx; i < s.length; i++) {
        generateSubseq(s, i + 1, curr + s[i], st);
    }
}

function checkSubseq(s, idx, curr, st) {
    if (curr.length > 0 && st.has(curr)) {
        return true;
    }

    if (idx === s.length) {
        return false;
    }

    for (let i = idx; i < s.length; i++) {
        if (checkSubseq(s, i + 1, curr + s[i], st)) {
            return true;
        }
    }

    return false;
}

function commonSubseq(s1, s2) {
    let st = new Set();

    // Generate subsequences of first string
    generateSubseq(s1, 0, "", st);

    // Check subsequences of second string
    return checkSubseq(s2, 0, "", st);
}

// Driver Code
let s1 = "ABEF";
let s2 = "CADE";

if (commonSubseq(s1, s2)) {
    console.log("true");
} else {
    console.log("false");
}

Output
true

Time Complexity: O(2^|s1| + 2^|s2|)
Auxiliary Space: O(2^|s1|)

[Expected Approach] Check Common Character - O(|s1| + |s2|) Time O(1) Space

The idea is that even a single common character between the two strings forms a common subsequence of length 1.

We store the presence of all characters of the first string in a frequency array. Then we traverse the second string and check whether any character is already marked present. If a common character is found, return true; otherwise, return false.

C++
#include <bits/stdc++.h>
using namespace std;

bool commonSubseq(string &s1, string &s2)
{

    // Frequency array for characters
    vector<int> freq(256, 0);

    // Mark characters of first string
    for (char ch : s1)
        freq[ch] = 1;

    // Check characters in second string
    for (char ch : s2)
    {

        // Common character found
        if (freq[ch])
            return true;
    }

    return false;
}

// Driver Code
int main()
{

    string s1 = "ABEF";
    string s2 = "CADE";

    if (commonSubseq(s1, s2))
        cout << "true";
    else
        cout << "false";

    return 0;
}
Java
import java.util.Arrays;

public class GfG {

    public static boolean commonSubseq(String s1, String s2) {

        // Frequency array for characters
        int[] freq = new int[256];

        // Mark characters of first string
        for (char ch : s1.toCharArray())
            freq[ch] = 1;

        // Check characters in second string
        for (char ch : s2.toCharArray()) {

            // Common character found
            if (freq[ch] == 1)
                return true;
        }

        return false;
    }

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

        if (commonSubseq(s1, s2))
            System.out.println("true");
        else
            System.out.println("false");
    }
}
Python
def commonSubseq(s1, s2):

    # Frequency array for characters
    freq = [0] * 256

    # Mark characters of first string
    for ch in s1:
        freq[ord(ch)] = 1

    # Check characters in second string
    for ch in s2:

        # Common character found
        if freq[ord(ch)]:
            return True

    return False

# Driver Code
if __name__ == "__main__":

    s1 = "ABEF"
    s2 = "CADE"

    if commonSubseq(s1, s2):
        print("true")
    else:
        print("false")
C#
using System;

public class GfG
{
    public static bool commonSubseq(string s1, string s2)
    {
        // Frequency array for characters
        int[] freq = new int[256];

        // Mark characters of first string
        foreach (char ch in s1)
            freq[ch] = 1;

        // Check characters in second string
        foreach (char ch in s2)
        {
            // Common character found
            if (freq[ch] == 1)
                return true;
        }

        return false;
    }

    public static void Main()
    {
        string s1 = "ABEF";
        string s2 = "CADE";

        if (commonSubseq(s1, s2))
            Console.WriteLine("true");
        else
            Console.WriteLine("false");
    }
}
JavaScript
function commonSubseq(s1, s2) {

    // Frequency array for characters
    let freq = new Array(256).fill(0);

    // Mark characters of first string
    for (let ch of s1) {
        freq[ch.charCodeAt(0)] = 1;
    }

    // Check characters in second string
    for (let ch of s2) {

        // Common character found
        if (freq[ch.charCodeAt(0)] === 1) {
            return true;
        }
    }

    return false;
}

// Driver Code
let s1 = "ABEF";
let s2 = "CADE";

if (commonSubseq(s1, s2)) {
    console.log('true');
} else {
    console.log('false');
}

Output
true

Time Complexity: O(|s1| + |s2|)
Auxiliary Space: O(1)

Comment