This can be solved using Dynamic programming, it hasoverlapping_subproblems

Code

# Dynamic Programming implementation of LCS problem
 
def lcs(X , Y, m, n):	
 
	# Declaring the array for storing the dp values
	L = [[None]*(n+1) for i in range(m+1)]
 
	# Following steps build L[m+1][n+1] in bottom up fashion
	# Note: L[i][j] contains length of LCS of X[0..i-1]
	# and Y[0..j-1]
	for i in range(m+1):
		for j in range(n+1):
			if i == 0 or j == 0 :
				L[i][j] = 0
			elif X[i-1] == Y[j-1]:
				L[i][j] = L[i-1][j-1]+1
			else:
				L[i][j] = max(L[i-1][j] , L[i][j-1])
 
	# L[m][n] contains the length of LCS of X[0..n-1] & Y[0..m-1]
	return L[m][n]
 
 
# Driver code
if __name__ == '__main__':
	S1 = "AGGTAB"
	S2 = "GXTXAYB"
	m = len(S1)
	n = len(S2)
	print ("Length of LCS is", lcs(S1, S2, m, n) )
 

Javascript

function longestCommonSubsequenceMemo(text1, text2) {
    const memo = new Map();
 
    function helper(m, n) {
        if (m === 0 || n === 0) {
            return 0;
        }
 
        const key = m + "," + n;
        if (memo.has(key)) {
            return memo.get(key);
        }
 
        let result;
        if (text1[m - 1] === text2[n - 1]) {
            result = 1 + helper(m - 1, n - 1);
        } else {
            result = Math.max(helper(m - 1, n), helper(m, n - 1));
        }
 
        memo.set(key, result);
        return result;
    }
 
    return helper(text1.length, text2.length);
}
 
// Example usage:
const text1 = "abcde";
const text2 = "ace";
console.log(longestCommonSubsequenceMemo(text1, text2)); // Output: 3
 
function longestCommonSubsequenceTab(text1, text2) {
    const m = text1.length;
    const n = text2.length;
    const dp = Array.from(Array(m + 1), () => Array(n + 1).fill(0));
 
    for (let i = 1; i <= m; i++) {
        for (let j = 1; j <= n; j++) {
            if (text1[i - 1] === text2[j - 1]) {
                dp[i][j] = 1 + dp[i - 1][j - 1];
            } else {
                dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
            }
        }
    }
 
    return dp[m][n];
}
 
// Example usage:
const text1 = "abcde";
const text2 = "ace";
console.log(longestCommonSubsequenceTab(text1, text2)); // Output: 3