Given two strings **A** and **B**. The task is to count the number of ways to insert a character in string A to increase the length of the Longest Common Subsequence between string A and string B by 1.

**Examples:**

Input : A = “aa”, B = “baaa”

Output : 4

The longest common subsequence shared by string A and string B is “aa”, which has a length of 2.

There are two ways that the length of the longest common subsequence can be increased to 3 by adding a single character to string A:

- There are 3 different positions in string A where we could insert an additional ‘a’ to create longest common subsequence “aaa” (i.e at the beginning, middle, and end of the string).
- We can insert a ‘b’ at the beginning of the string for a new longest common subsequence of “baaa”. So, we have 3 + 1 = 4 ways to insert an alphanumeric character into string A and increase the length of the longest common subsequence by one.

Let say for a given string A and string B, the length of their LCS is **k**. Let’s insert a single character ‘c’ after the ith character in string A and denote the string formed after the insertion as string A_{new}, which looks like:

A_{new} = A_{1, i} . c . A_{i + 1, n}

where A_{i, j} denotes a substring of string A from the ith to the jth characters and ‘.’ denotes a concatenation of two strings.

Let’s define k_{new} to be the length of the LCS of A_{new} and B. Now we want to know if k_{new} = k + 1.

The crucial observation is that the newly inserted character ‘c’ must be a part of any common subsequence of A_{new} and B having length > k. We know this because if there is any common subsequence of A_{new} and B, this is a contradiction because it would mean the length of the LCS of A and B is > k.

Using the above observation, we can try the following approach. For each possible character ‘c'(there are 52 upper and lower case English letters and 10 Arabic digits, so there are 62 possible characters to insert) and for every possible insertion i in String A (there are |a| + 1 insertion positions), let’s try to insert ‘c’ after the ith character in string A and match it with every occurrence of ‘c’ in string B, we can try to match these ‘c’ characters such that:

A_{1, i} . c . A_{i+1, n}

B_{1, j-1} . c . B_{j+1, m}

Now, in order to check if such an insertion produces an LCS of length k + 1, it’s sufficienet to check if the length of the LCS of A_{1, i} and B_{1, j-1} plus the length of the LCS A_{i+1, n} and B_{j+1, m} is equal to k. In this case, the lCS of A_{new} and B is k + 1 because there is both a match between the fixed occurances of character ‘c’ and there is no longer common subsequence between them.

If we can quickly get the length of the LCS between every two prefixes of A and B as well as between every two of their suffixes, we can compute the result. The length of the LCS between their prefixes can be read from a Dynamic Programming table used in computing the LCS of string A and string B. In this method, dp[i][j] stores the length of longest common subsequence of A_{, i} and B_{i, j}. Similarly, the length of the LCS between their suffixes can be read from an analogous dp table which can be computed during computation of the LCS of A_{reversed} and B_{reversed} where S_{reversed} denotes the reversed string S.

## C++

`// CPP Program to Number of ways to insert a ` `// character to increase LCS by one ` `#include <bits/stdc++.h> ` `#define MAX 256 ` `using` `namespace` `std; ` ` ` `// Return the Number of ways to insert a ` `// character to increase the Longest ` `// Common Subsequence by one ` `int` `numberofways(string A, string B, ` `int` `N, ` `int` `M) ` `{ ` ` ` `vector<` `int` `> pos[MAX]; ` ` ` ` ` `// Insert all positions of all characters ` ` ` `// in string B. ` ` ` `for` `(` `int` `i = 0; i < M; i++) ` ` ` `pos[B[i]].push_back(i + 1); ` ` ` ` ` `// Longest Common Subsequence ` ` ` `int` `dpl[N + 2][M + 2]; ` ` ` `memset` `(dpl, 0, ` `sizeof` `(dpl)); ` ` ` `for` `(` `int` `i = 1; i <= N; i++) { ` ` ` `for` `(` `int` `j = 1; j <= M; j++) { ` ` ` `if` `(A[i - 1] == B[j - 1]) ` ` ` `dpl[i][j] = dpl[i - 1][j - 1] + 1; ` ` ` `else` ` ` `dpl[i][j] = max(dpl[i - 1][j], ` ` ` `dpl[i][j - 1]); ` ` ` `} ` ` ` `} ` ` ` `int` `LCS = dpl[N][M]; ` ` ` ` ` `// Longest Common Subsequence from reverse ` ` ` `int` `dpr[N + 2][M + 2]; ` ` ` `memset` `(dpr, 0, ` `sizeof` `(dpr)); ` ` ` `for` `(` `int` `i = N; i >= 1; i--) { ` ` ` `for` `(` `int` `j = M; j >= 1; j--) { ` ` ` `if` `(A[i - 1] == B[j - 1]) ` ` ` `dpr[i][j] = dpr[i + 1][j + 1] + 1; ` ` ` `else` ` ` `dpr[i][j] = max(dpr[i + 1][j], ` ` ` `dpr[i][j + 1]); ` ` ` `} ` ` ` `} ` ` ` ` ` `// inserting character between position ` ` ` `// i and i+1 ` ` ` `int` `ans = 0; ` ` ` `for` `(` `int` `i = 0; i <= N; i++) { ` ` ` `for` `(` `int` `j = 0; j < MAX; j++) { ` ` ` `for` `(` `auto` `x : pos[j]) { ` ` ` `if` `(dpl[i][x - 1] + dpr[i + 1][x + 1] == LCS) { ` ` ` `ans++; ` ` ` `break` `; ` ` ` `} ` ` ` `} ` ` ` `} ` ` ` `} ` ` ` ` ` `return` `ans; ` `} ` ` ` `// Driver Program ` `int` `main() ` `{ ` ` ` `string A = ` `"aa"` `, B = ` `"baaa"` `; ` ` ` `int` `N = A.length(), M = B.length(); ` ` ` `cout << numberofways(A, B, N, M) << endl; ` ` ` `return` `0; ` `} ` |

*chevron_right*

*filter_none*

## Java

`// Java Program for Number of ways to insert a ` `// character to increase LCS by one ` `import` `java.util.*; ` ` ` `class` `GFG ` `{ ` ` ` `static` `final` `int` `MAX = ` `256` `; ` ` ` ` ` `// Return the Number of ways to insert a ` ` ` `// character to increase the Longest ` ` ` `// Common Subsequence by one ` ` ` `static` `int` `numberofways(String A, String B, ` `int` `N, ` `int` `M) ` ` ` `{ ` ` ` `Vector<Integer>[] pos = ` `new` `Vector[MAX]; ` ` ` ` ` `// Insert all positions of all characters ` ` ` `// in string B. ` ` ` `for` `(` `int` `i = ` `0` `; i < MAX; i++) ` ` ` `pos[i] = ` `new` `Vector<>(); ` ` ` ` ` `for` `(` `int` `i = ` `0` `; i < M; i++) ` ` ` `pos[B.charAt(i)].add(i + ` `1` `); ` ` ` ` ` `// Longest Common Subsequence ` ` ` `int` `[][] dpl = ` `new` `int` `[N + ` `2` `][M + ` `2` `]; ` ` ` `for` `(` `int` `i = ` `1` `; i <= N; i++) ` ` ` `{ ` ` ` `for` `(` `int` `j = ` `1` `; j <= M; j++) ` ` ` `{ ` ` ` `if` `(A.charAt(i - ` `1` `) == B.charAt(j - ` `1` `)) ` ` ` `dpl[i][j] = dpl[i - ` `1` `][j - ` `1` `] + ` `1` `; ` ` ` `else` ` ` `dpl[i][j] = Math.max(dpl[i - ` `1` `][j], ` ` ` `dpl[i][j - ` `1` `]); ` ` ` `} ` ` ` `} ` ` ` `int` `LCS = dpl[N][M]; ` ` ` ` ` `// Longest Common Subsequence from reverse ` ` ` `int` `[][] dpr = ` `new` `int` `[N + ` `2` `][M + ` `2` `]; ` ` ` `for` `(` `int` `i = N; i >= ` `1` `; i--) ` ` ` `{ ` ` ` `for` `(` `int` `j = M; j >= ` `1` `; j--) ` ` ` `{ ` ` ` `if` `(A.charAt(i - ` `1` `) == B.charAt(j - ` `1` `)) ` ` ` `dpr[i][j] = dpr[i + ` `1` `][j + ` `1` `] + ` `1` `; ` ` ` `else` ` ` `dpr[i][j] = Math.max(dpr[i + ` `1` `][j], ` ` ` `dpr[i][j + ` `1` `]); ` ` ` `} ` ` ` `} ` ` ` ` ` `// inserting character between position ` ` ` `// i and i+1 ` ` ` `int` `ans = ` `0` `; ` ` ` `for` `(` `int` `i = ` `0` `; i <= N; i++) ` ` ` `{ ` ` ` `for` `(` `int` `j = ` `0` `; j < MAX; j++) ` ` ` `{ ` ` ` `for` `(` `int` `x : pos[j]) ` ` ` `{ ` ` ` `if` `(dpl[i][x - ` `1` `] + ` ` ` `dpr[i + ` `1` `][x + ` `1` `] == LCS) ` ` ` `{ ` ` ` `ans++; ` ` ` `break` `; ` ` ` `} ` ` ` `} ` ` ` `} ` ` ` `} ` ` ` `return` `ans; ` ` ` `} ` ` ` ` ` `// Driver Code ` ` ` `public` `static` `void` `main(String[] args) ` ` ` `{ ` ` ` `String A = ` `"aa"` `, B = ` `"baaa"` `; ` ` ` `int` `N = A.length(), M = B.length(); ` ` ` `System.out.println(numberofways(A, B, N, M)); ` ` ` `} ` `} ` ` ` `// This code is contributed by ` `// sanjeev2552 ` |

*chevron_right*

*filter_none*

## Python3

`# Python Program to Number of ways to insert a ` `# character to increase LCS by one ` ` ` `MAX` `=` `256` ` ` ` ` `def` `numberofways(A, B, N, M): ` ` ` `pos ` `=` `[[] ` `for` `_ ` `in` `range` `(` `MAX` `)] ` ` ` ` ` `# Insert all positions of all characters ` ` ` `# in string B ` ` ` `for` `i ` `in` `range` `(M): ` ` ` `pos[` `ord` `(B[i])].append(i` `+` `1` `) ` ` ` ` ` `# Longest Common Subsequence ` ` ` `dpl ` `=` `[[` `0` `] ` `*` `(M` `+` `2` `) ` `for` `_ ` `in` `range` `(N` `+` `2` `)] ` ` ` `for` `i ` `in` `range` `(` `1` `, N` `+` `1` `): ` ` ` `for` `j ` `in` `range` `(` `1` `, M` `+` `1` `): ` ` ` `if` `A[i ` `-` `1` `] ` `=` `=` `B[j ` `-` `1` `]: ` ` ` `dpl[i][j] ` `=` `dpl[i ` `-` `1` `][j ` `-` `1` `] ` `+` `1` ` ` `else` `: ` ` ` `dpl[i][j] ` `=` `max` `(dpl[i ` `-` `1` `][j], ` ` ` `dpl[i][j ` `-` `1` `]) ` ` ` ` ` `LCS ` `=` `dpl[N][M] ` ` ` ` ` `# Longest Common Subsequence from reverse ` ` ` `dpr ` `=` `[[` `0` `] ` `*` `(M` `+` `2` `) ` `for` `_ ` `in` `range` `(N` `+` `2` `)] ` ` ` `for` `i ` `in` `range` `(N, ` `0` `, ` `-` `1` `): ` ` ` `for` `j ` `in` `range` `(M, ` `0` `, ` `-` `1` `): ` ` ` `if` `A[i ` `-` `1` `] ` `=` `=` `B[j ` `-` `1` `]: ` ` ` `dpr[i][j] ` `=` `dpr[i ` `+` `1` `][j ` `+` `1` `] ` `+` `1` ` ` `else` `: ` ` ` `dpr[i][j] ` `=` `max` `(dpr[i ` `+` `1` `][j], ` ` ` `dpr[i][j ` `+` `1` `]) ` ` ` ` ` `# inserting character between position ` ` ` `# i and i+1 ` ` ` `ans ` `=` `0` ` ` `for` `i ` `in` `range` `(N` `+` `1` `): ` ` ` `for` `j ` `in` `range` `(` `MAX` `): ` ` ` `for` `x ` `in` `pos[j]: ` ` ` `if` `dpl[i][x ` `-` `1` `] ` `+` `dpr[i ` `+` `1` `][x ` `+` `1` `] ` `=` `=` `LCS: ` ` ` `ans ` `+` `=` `1` ` ` `break` ` ` ` ` `return` `ans ` ` ` ` ` `# Driver Code ` `if` `__name__ ` `=` `=` `"__main__"` `: ` ` ` `A ` `=` `"aa"` ` ` `B ` `=` `"baaa"` ` ` `N ` `=` `len` `(A) ` ` ` `M ` `=` `len` `(B) ` ` ` `print` `(numberofways(A, B, N, M)) ` ` ` `# This code is contributed by vibhu4agarwal ` |

*chevron_right*

*filter_none*

## C#

`// C# Program for Number of ways to insert a ` `// character to increase LCS by one ` `using` `System; ` `using` `System.Collections.Generic; ` ` ` `class` `GFG ` `{ ` ` ` `static` `readonly` `int` `MAX = 256; ` ` ` ` ` `// Return the Number of ways to insert a ` ` ` `// character to increase the longest ` ` ` `// Common Subsequence by one ` ` ` `static` `int` `numberofways(String A, String B, ` ` ` `int` `N, ` `int` `M) ` ` ` `{ ` ` ` `List<` `int` `>[] pos = ` `new` `List<` `int` `>[MAX]; ` ` ` ` ` `// Insert all positions of all characters ` ` ` `// in string B. ` ` ` `for` `(` `int` `i = 0; i < MAX; i++) ` ` ` `pos[i] = ` `new` `List<` `int` `>(); ` ` ` ` ` `for` `(` `int` `i = 0; i < M; i++) ` ` ` `pos[B[i]].Add(i + 1); ` ` ` ` ` `// longest Common Subsequence ` ` ` `int` `[,] dpl = ` `new` `int` `[N + 2, M + 2]; ` ` ` `for` `(` `int` `i = 1; i <= N; i++) ` ` ` `{ ` ` ` `for` `(` `int` `j = 1; j <= M; j++) ` ` ` `{ ` ` ` `if` `(A[i - 1] == B[j - 1]) ` ` ` `dpl[i, j] = dpl[i - 1, j - 1] + 1; ` ` ` `else` ` ` `dpl[i, j] = Math.Max(dpl[i - 1, j], ` ` ` `dpl[i, j - 1]); ` ` ` `} ` ` ` `} ` ` ` `int` `LCS = dpl[N, M]; ` ` ` ` ` `// longest Common Subsequence from reverse ` ` ` `int` `[,] dpr = ` `new` `int` `[N + 2, M + 2]; ` ` ` `for` `(` `int` `i = N; i >= 1; i--) ` ` ` `{ ` ` ` `for` `(` `int` `j = M; j >= 1; j--) ` ` ` `{ ` ` ` `if` `(A[i - 1] == B[j - 1]) ` ` ` `dpr[i, j] = dpr[i + 1, j + 1] + 1; ` ` ` `else` ` ` `dpr[i, j] = Math.Max(dpr[i + 1, j], ` ` ` `dpr[i, j + 1]); ` ` ` `} ` ` ` `} ` ` ` ` ` `// inserting character between position ` ` ` `// i and i+1 ` ` ` `int` `ans = 0; ` ` ` `for` `(` `int` `i = 0; i <= N; i++) ` ` ` `{ ` ` ` `for` `(` `int` `j = 0; j < MAX; j++) ` ` ` `{ ` ` ` `foreach` `(` `int` `x ` `in` `pos[j]) ` ` ` `{ ` ` ` `if` `(dpl[i, x - 1] + ` ` ` `dpr[i + 1, x + 1] == LCS) ` ` ` `{ ` ` ` `ans++; ` ` ` `break` `; ` ` ` `} ` ` ` `} ` ` ` `} ` ` ` `} ` ` ` `return` `ans; ` ` ` `} ` ` ` ` ` `// Driver Code ` ` ` `public` `static` `void` `Main(String[] args) ` ` ` `{ ` ` ` `String A = ` `"aa"` `, B = ` `"baaa"` `; ` ` ` `int` `N = A.Length, M = B.Length; ` ` ` `Console.WriteLine(numberofways(A, B, N, M)); ` ` ` `} ` `} ` ` ` `// This code is contributed by 29AjayKumar ` |

*chevron_right*

*filter_none*

**Output:**

4

**Time Complexity:** O(N x M)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the **DSA Self Paced Course** at a student-friendly price and become industry ready.

## Recommended Posts:

- Count ways to increase LCS length of two strings by one
- A Space Optimized Solution of LCS
- Longest Common Increasing Subsequence (LCS + LIS)
- LCS (Longest Common Subsequence) of three strings
- LCS formed by consecutive segments of at least length K
- Edit distance and LCS (Longest Common Subsequence)
- Check if frequency of character in one string is a factor or multiple of frequency of same character in other string
- Map every character of one string to another such that all occurrences are mapped to the same character
- Number of ways to insert two pairs of parentheses into a string of N characters
- Sub-strings that start and end with one character and have at least one other
- Insert a Character in a Rotated String
- Number of ways to convert a character X to a string Y
- Ways to split string such that each partition starts with distinct character
- Longest Common Prefix using Character by Character Matching
- Find a string such that every character is lexicographically greater than its immediate next character
- Replace every character of string by character whose ASCII value is K times more than it
- Count substrings that starts with character X and ends with character Y
- Replace every character of a string by a different character
- Shortest distance to every other character from given character
- Modify the string such that every character gets replaced with the next character in the keyboard

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.