Longest Repeated Subsequence (original) (raw)
Last Updated : 15 Nov, 2024
Given a **string s, the task is to find the **longest repeating subsequence, such that the two subsequences **don’t have the **same string character at the same position, i.e. any ith character in the two subsequences shouldn’t have the same index in the original string.
**Examples:
**Input: s = "aabb"
**Output: "ab"
**Explanation: The longest repeated subsequence is "ab", formed by matching 'a' from positions 1 and 2, and 'b' from positions 3 and 4.**Input: s = "aab"
**Output: "a"
**Explanation: The two subsequences are 'a'(first) and 'a' (second). Note that 'b' cannot be considered as part of a subsequence as it would be at the same index in both.
This problem is just the modification of the Longest Common Subsequence problem. The idea is to find th**e LCS(s, s) where **s is the input string with the restriction that when both the characters are the same, they **shouldn't be on the same index in the two strings. We have discussed a solution to find the length of the longest repeated subsequence.
C++ `
// C++ program to find the longest repeating // subsequence #include #include using namespace std;
int longestRepeatingSubsequence(string s) { int n = s.length();
// Create and initialize DP table
int dp[n + 1][n + 1];
for (int i = 0; i <= n; i++)
for (int j = 0; j <= n; j++)
dp[i][j] = 0;
// Fill dp table (similar to LCS loops)
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
// If characters match and indexes are
// not same
if (s[i - 1] == s[j - 1] && i != j)
dp[i][j] = 1 + dp[i - 1][j - 1];
// If characters do not match
else
dp[i][j] = max(dp[i][j - 1], dp[i - 1][j]);
}
}
return dp[n][n];}
int main() { string s = "aabb"; int res = longestRepeatingSubsequence(s); cout << res << endl; return 0; }
Java
// Java program to find the longest // repeating subsequence
import java.io.; import java.util.;
class GfG {
// Function to find the longest repeating subsequence
static int longestRepeatingSubsequence(String s) {
int n = s.length();
// Create and initialize DP table
int[][] dp = new int[n + 1][n + 1];
// Fill dp table (similar to LCS loops)
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
// If characters match and indexes are not
// same
if (s.charAt(i - 1) == s.charAt(j - 1)
&& i != j)
dp[i][j] = 1 + dp[i - 1][j - 1];
// If characters do not match
else
dp[i][j] = Math.max(dp[i][j - 1],
dp[i - 1][j]);
}
}
return dp[n][n];
}
public static void main(String[] args) {
String s = "aabb";
int res = longestRepeatingSubsequence(s);
System.out.print(res);
}}
Python
Python 3 program to find the longest repeating
subsequence
def longestRepeatingSubsequence(s):
n = len(s)
# Create and initialize DP table
dp = [[0 for i in range(n + 1)] for j in range(n + 1)]
# Fill dp table (similar to LCS loops)
for i in range(1, n + 1):
for j in range(1, n + 1):
# If characters match and indexes are
# not same
if (s[i - 1] == s[j - 1] and i != j):
dp[i][j] = 1 + dp[i - 1][j - 1]
# If characters do not match
else:
dp[i][j] = max(dp[i][j - 1], dp[i - 1][j])
return dp[n][n]if name == 'main': s = "aabb" print(longestRepeatingSubsequence(s))
C#
// C# program to find the longest repeating // subsequence using System;
class GfG {
// Function to find the longest repeating
// subsequence
static int longestRepeatingSubsequence(string s) {
int n = s.Length;
// Create and initialize DP table
int[, ] dp = new int[n + 1, n + 1];
// Fill dp table (similar to LCS loops)
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
// If characters match and indexes
// are not same
if (s[i - 1] == s[j - 1] && i != j)
dp[i, j] = 1 + dp[i - 1, j - 1];
// If characters do not match
else
dp[i, j] = Math.Max(dp[i, j - 1],
dp[i - 1, j]);
}
}
return dp[n, n];
}
static void Main() {
string s = "aabb";
int res = longestRepeatingSubsequence(s);
Console.Write(res);
}}
JavaScript
// Javascript program to find the longest repeating // subsequence
function longestRepeatingSubsequence(s) { var n = s.length;
// Create and initialize DP table
var dp = new Array(n + 1);
for (var i = 0; i <= n; i++) {
dp[i] = new Array(n + 1);
for (var j = 0; j <= n; j++) {
dp[i][j] = 0;
}
}
// Fill dp table (similar to LCS loops)
for (var i = 1; i <= n; i++) {
for (var j = 1; j <= n; j++) {
// If characters match and indexes are
// not same
if ((s[i - 1] == s[j - 1]) && (i != j))
dp[i][j] = 1 + dp[i - 1][j - 1];
// If characters do not match
else
dp[i][j]
= Math.max(dp[i][j - 1], dp[i - 1][j]);
}
}
return dp[n][n];}
var s = "aabb"; let res = longestRepeatingSubsequence(s); console.log(res);
`
**Time Complexity: O(n*n), where **n is the length of string s.
**Auxilairy Space: O(n*n)
**How to print the subsequence?
The above solution only finds **length of subsequence. We can print the subsequence using **dp[n+1][n+1] table The idea is similar to printing LCS.
C++ `
// C++ program to print the longest repeated // subsequence
#include <bits/stdc++.h> using namespace std;
string longestRepeatedSubSeq(string s) {
// THIS PART OF CODE IS
// FILLS dp[][]
int n = s.length();
int dp[n + 1][n + 1];
for (int i = 0; i <= n; i++) {
for (int j = 0; j <= n; j++) {
dp[i][j] = 0;
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (s[i - 1] == s[j - 1] && i != j) {
dp[i][j] = 1 + dp[i - 1][j - 1];
}
else {
dp[i][j] = max(dp[i][j - 1], dp[i - 1][j]);
}
}
}
// THIS PART OF CODE FINDS THE RESULT STRING USING DP[][]
// Initialize result
string res = "";
// Traverse dp[][] from bottom right
int i = n, j = n;
while (i > 0 && j > 0) {
// If this cell is same as diagonally
// adjacent cell just above it, then
// same characters are present at
// str[i-1] and str[j-1]. Append any
// of them to result.
if (dp[i][j] == dp[i - 1][j - 1] + 1) {
res = res + s[i - 1];
i--;
j--;
}
// Otherwise we move to the side
// that gave us maximum result
else if (dp[i][j] == dp[i - 1][j]) {
i--;
}
else {
j--;
}
}
// Since we traverse dp[][] from bottom,
// we get result in reverse order.
reverse(res.begin(), res.end());
return res;}
int main() {
string s = "AABEBCDD";
cout << longestRepeatedSubSeq(s);
return 0;}
Java
// Java program to print the longest repeated // subsequence
import java.util.*;
class GfG {
static String longestRepeatedSubSeq(String s) {
// THIS PART OF CODE
// FILLS dp[][]
int n = s.length();
int[][] dp = new int[n + 1][n + 1];
for (int i = 0; i <= n; i++) {
for (int j = 0; j <= n; j++) {
dp[i][j] = 0;
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (s.charAt(i - 1) == s.charAt(j - 1)
&& i != j) {
dp[i][j] = 1 + dp[i - 1][j - 1];
}
else {
dp[i][j] = Math.max(dp[i][j - 1],
dp[i - 1][j]);
}
}
}
// THIS PART OF CODE FINDS
// THE RESULT STRING USING DP[][]
// Initialize result
String res = "";
// Traverse dp[][] from bottom right
int i = n, j = n;
while (i > 0 && j > 0) {
// If this cell is same as diagonally
// adjacent cell just above it, then
// same characters are present at
// str[i-1] and str[j-1]. Append any
// of them to result.
if (dp[i][j] == dp[i - 1][j - 1] + 1) {
res = res + s.charAt(i - 1);
i--;
j--;
}
// Otherwise we move to the side
// that gave us maximum result
else if (dp[i][j] == dp[i - 1][j]) {
i--;
}
else {
j--;
}
}
// Since we traverse dp[][] from bottom,
// we get result in reverse order.
String reverse = "";
for (int k = res.length() - 1; k >= 0; k--) {
reverse = reverse + res.charAt(k);
}
return reverse;
}
public static void main(String args[]) {
String str = "AABEBCDD";
System.out.println(longestRepeatedSubSeq(str));
}}
Python
Python3 program to print the
longest repeated subsequence
def longestRepeatedSubSeq(s):
# This part of code
# fills dp[][]
n = len(s)
dp = [[0 for i in range(n + 1)] for j in range(n + 1)]
for i in range(1, n + 1):
for j in range(1, n + 1):
if (s[i - 1] == s[j - 1] and i != j):
dp[i][j] = 1 + dp[i - 1][j - 1]
else:
dp[i][j] = max(dp[i][j - 1], dp[i - 1][j])
# This part of code finds the result
# string using dp[][] Initialize result
res = ''
# Traverse dp[][] from bottom right
i = n
j = n
while (i > 0 and j > 0):
# If this cell is same as diagonally
# adjacent cell just above it, then
# same characters are present at
# str[i-1] and str[j-1]. Append any
# of them to result.
if (dp[i][j] == dp[i - 1][j - 1] + 1):
res += s[i - 1]
i -= 1
j -= 1
# Otherwise we move to the side
# that gave us maximum result.
elif (dp[i][j] == dp[i - 1][j]):
i -= 1
else:
j -= 1
# Since we traverse dp[][] from bottom,
# we get result in reverse order.
res = ''.join(reversed(res))
return ress = 'AABEBCDD' print(longestRepeatedSubSeq(s))
C#
// C# program to print the longest repeated // subsequence using System; using System.Collections.Generic;
class GfG {
static String longestRepeatedSubSeq(String s) {
// THIS PART OF CODE
// FILLS dp[,]
int n = s.Length, i, j;
int[, ] dp = new int[n + 1, n + 1];
for (i = 0; i <= n; i++) {
for (j = 0; j <= n; j++) {
dp[i, j] = 0;
}
}
for (i = 1; i <= n; i++) {
for (j = 1; j <= n; j++) {
if (s[i - 1] == s[j - 1] && i != j) {
dp[i, j] = 1 + dp[i - 1, j - 1];
}
else {
dp[i, j] = Math.Max(dp[i, j - 1],
dp[i - 1, j]);
}
}
}
// THIS PART OF CODE FINDS
// THE RESULT STRING USING DP[,]
// Initialize result
String res = "";
// Traverse dp[,] from bottom right
i = n;
j = n;
while (i > 0 && j > 0) {
// If this cell is same as diagonally
// adjacent cell just above it, then
// same characters are present at
// str[i-1] and str[j-1]. Append any
// of them to result.
if (dp[i, j] == dp[i - 1, j - 1] + 1) {
res = res + s[i - 1];
i--;
j--;
}
// Otherwise we move to the side
// that gave us maximum result
else if (dp[i, j] == dp[i - 1, j])
i--;
else
j--;
}
// Since we traverse dp[,] from bottom,
// we get result in reverse order.
String reverse = "";
for (int k = res.Length - 1; k >= 0; k--) {
reverse = reverse + res[k];
}
return reverse;
}
static void Main(String[] args) {
String s = "AABEBCDD";
Console.WriteLine(longestRepeatedSubSeq(s));
}}
JavaScript
// Javascript program to print the longest repeated // subsequence
function longestRepeatedSubSeq(s) {
// THIS PART OF CODE
// FILLS dp[][]
let n = s.length;
let dp = new Array(n + 1);
for (let i = 0; i <= n; i++) {
dp[i] = new Array(n + 1);
for (let j = 0; j <= n; j++) {
dp[i][j] = 0;
}
}
for (let i = 1; i <= n; i++) {
for (let j = 1; j <= n; j++) {
if (s[i - 1] == s[j - 1] && i != j) {
dp[i][j] = 1 + dp[i - 1][j - 1];
} else {
dp[i][j] = Math.max(dp[i][j - 1], dp[i - 1][j]);
}
}
}
// THIS PART OF CODE FINDS
// THE RESULT STRING USING DP[][]
// Initialize result
let res = "";
// Traverse dp[][] from bottom right
let i = n, j = n;
while (i > 0 && j > 0) {
// If this cell is same as diagonally
// adjacent cell just above it, then
// same characters are present at
// str[i-1] and str[j-1]. Append any
// of them to result.
if (dp[i][j] == dp[i - 1][j - 1] + 1) {
res = res + s[i - 1];
i--;
j--;
}
// Otherwise we move to the side
// that gave us maximum result
else if (dp[i][j] == dp[i - 1][j]) {
i--;
} else {
j--;
}
}
// Since we traverse dp[][] from bottom,
// we get result in reverse order.
let reverse = "";
for (let k = res.length - 1; k >= 0; k--) {
reverse = reverse + res[k];
}
return reverse;}
let s = "AABEBCDD"; console.log(longestRepeatedSubSeq(s));
`
**Time Complexity: O(n*n), where **n is the length of string s.
**Auxilairy Space: O(n*n)