Longest Repeated Subsequence
Given a string, print the longest repeating subsequence such that the two subsequence don’t have same string character at same position, i.e., any i’th character in the two subsequences shouldn’t have the same index in the original string.
Examples:
Input: str = "aabb"
Output: "ab"
Input: str = "aab"
Output: "a"
The two subsequence are 'a'(first) and 'a'
(second). Note that 'b' cannot be considered
as part of subsequence as it would be at same
index in both.
This problem is just the modification of Longest Common Subsequence problem. The idea is to find the LCS(str, str) where str is the input string with the restriction that when both the characters are same, they shouldn’t be on the same index in the two strings.
We have discussed a solution to find length of the longest repeated subsequence.
C++
Java
Python3
C#
PHP
Javascript
<script>
function findLongestRepeatingSubSeq(str)
{
let n = str.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 (str[i - 1] == str[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]);
}
}
return dp[n][n];
}
</script>
|
Time Complexity: O(n^2)
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 built. The idea is similar to printing LCS.
// Pseudo code to find longest repeated
// subsequence using the dp[][] table filled
// above.
// 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 + str[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;
Below is implementation of above steps.
C++
#include <bits/stdc++.h>
using namespace std;
string longestRepeatedSubSeq(string str)
{
int n = str.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 (str[i-1] == str[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]);
string res = "" ;
int i = n, j = n;
while (i > 0 && j > 0)
{
if (dp[i][j] == dp[i-1][j-1] + 1)
{
res = res + str[i-1];
i--;
j--;
}
else if (dp[i][j] == dp[i-1][j])
i--;
else
j--;
}
reverse(res.begin(), res.end());
return res;
}
int main()
{
string str = "AABEBCDD" ;
cout << longestRepeatedSubSeq(str);
return 0;
}
|
Java
import java.util.*;
class GFG
{
static String longestRepeatedSubSeq(String str)
{
int n = str.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 (str.charAt(i - 1 ) == str.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]);
String res = "" ;
int i = n, j = n;
while (i > 0 && j > 0 )
{
if (dp[i][j] == dp[i - 1 ][j - 1 ] + 1 )
{
res = res + str.charAt(i - 1 );
i--;
j--;
}
else if (dp[i][j] == dp[i - 1 ][j])
i--;
else
j--;
}
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));
}
}
|
Python3
def longestRepeatedSubSeq( str ):
n = len ( str )
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 ( str [i - 1 ] = = str [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])
res = ''
i = n
j = n
while (i > 0 and j > 0 ):
if (dp[i][j] = = dp[i - 1 ][j - 1 ] + 1 ):
res + = str [i - 1 ]
i - = 1
j - = 1
elif (dp[i][j] = = dp[i - 1 ][j]):
i - = 1
else :
j - = 1
res = ''.join( reversed (res))
return res
str = 'AABEBCDD'
print (longestRepeatedSubSeq( str ))
|
PHP
<?php
function longestRepeatedSubSeq( $str )
{
$n = strlen ( $str );
$dp = array ( array ());
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 ( $str [ $i - 1] == $str [ $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 ]);
$res = "" ;
$i = $n ;
$j = $n ;
while ( $i > 0 && $j > 0)
{
if ( $dp [ $i ][ $j ] == $dp [ $i - 1][ $j - 1] + 1)
{
$res = $res . $str [ $i - 1];
$i --;
$j --;
}
else if ( $dp [ $i ][ $j ] == $dp [ $i - 1][ $j ])
$i --;
else
$j --;
}
return strrev ( $res ) ;
}
$str = "AABEBCDD" ;
echo longestRepeatedSubSeq( $str );
?>
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static String longestRepeatedSubSeq(String str)
{
int n = str.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 (str[i - 1] == str[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]);
String res = "" ;
i = n; j= n;
while (i > 0 && j > 0)
{
if (dp[i, j] == dp[i - 1,j - 1] + 1)
{
res = res + str[i - 1];
i--;
j--;
}
else if (dp[i,j] == dp[i - 1,j])
i--;
else
j--;
}
String reverse = "" ;
for ( int k = res.Length - 1; k >= 0; k--)
{
reverse = reverse + res[k];
}
return reverse;
}
public static void Main(String []args)
{
String str = "AABEBCDD" ;
Console.WriteLine(longestRepeatedSubSeq(str));
}
}
|
Javascript
<script>
function longestRepeatedSubSeq(str)
{
subsequence/
let n = str.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 (str[i-1] == str[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]);
let res = "" ;
let i = n, j = n;
while (i > 0 && j > 0)
{
if (dp[i][j] == dp[i - 1][j - 1] + 1)
{
res = res + str[i-1];
i--;
j--;
}
else if (dp[i][j] == dp[i - 1][j])
i--;
else
j--;
}
let reverse = "" ;
for (let k = res.length - 1; k >= 0; k--)
{
reverse = reverse + res[k];
}
return reverse;
}
let str = "AABEBCDD" ;
document.write(longestRepeatedSubSeq(str));
</script>
|
Output:
ABD
Time Complexity : O(n2)
Auxiliary Space : O(n2)
Last Updated :
10 May, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...