Given a string, find the length of the longest repeating subsequence, such that the two subsequences don’t have 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: str = "abc"
Output: 0
There is no repeating subsequence
Input: str = "aab"
Output: 1
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.
Input: str = "aabb"
Output: 2
Input: str = "axxxy"
Output: 2
Method 1: 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.
- Initialize the input string, which is to be checked.
- Initialize the length of string to the variable.
- create a DP table using 2D matrix and set each element to 0.
- Fill the table if the characters are same and indexes are different.
- Return the values inside the table
- Print the String.
Below is the implementation of the idea.
C++
#include <iostream>
#include <string>
using namespace std;
int findLongestRepeatingSubSeq(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]);
}
}
return dp[n][n];
}
int main()
{
string str = "aabb" ;
cout << "The length of the largest subsequence that"
" repeats itself is : "
<< findLongestRepeatingSubSeq(str);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class LRS
{
static int findLongestRepeatingSubSeq(String str)
{
int n = str.length();
int [][] dp = new int [n+ 1 ][n+ 1 ];
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]);
}
}
return dp[n][n];
}
public static void main (String[] args)
{
String str = "aabb" ;
System.out.println( "The length of the largest subsequence that"
+ " repeats itself is : " +findLongestRepeatingSubSeq(str));
}
}
|
Python3
def findLongestRepeatingSubSeq( 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])
return dp[n][n]
if __name__ = = '__main__' :
str = "aabb"
print ( "The length of the largest subsequence that repeats itself is : "
,findLongestRepeatingSubSeq( str ))
|
C#
using System;
class GFG {
static int findLongestRepeatingSubSeq( string str)
{
int n = str.Length;
int [,]dp = new int [n+1,n+1];
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] = Math.Max(dp[i,j-1],
dp[i-1,j]);
}
}
return dp[n,n];
}
public static void Main ()
{
string str = "aabb" ;
Console.Write( "The length of the largest "
+ "subsequence that repeats itself is : "
+ findLongestRepeatingSubSeq(str));
}
}
|
PHP
<?php
function findLongestRepeatingSubSeq( $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 ]);
}
}
return $dp [ $n ][ $n ];
}
$str = "aabb" ;
echo "The length of the largest " .
"subsequence that repeats itself is : " ,
findLongestRepeatingSubSeq( $str );
?>
|
Javascript
<script>
function findLongestRepeatingSubSeq(str)
{
var n = str.length;
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;
}
}
for ( var i=1; i<=n; i++)
{
for ( var 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];
}
var str = "aabb" ;
document.write( "The length of the largest subsequence that repeats itself is : " + findLongestRepeatingSubSeq(str));
</script>
|
Output
The length of the largest subsequence that repeats itself is : 2
Time Complexity: O(n2)
Auxiliary Space: O(n2)
Method 2: (Using recursion)
C++
#include <bits/stdc++.h>
using namespace std;
int dp[1000][1000];
int findLongestRepeatingSubSeq(string X, int m, int n)
{
if (dp[m][n]!=-1)
return dp[m][n];
if (m == 0 || n == 0)
return dp[m][n] = 0;
if (X[m - 1] == X[n - 1] && m != n)
return dp[m][n] = findLongestRepeatingSubSeq(X,
m - 1, n - 1) + 1;
return dp[m][n] = max (findLongestRepeatingSubSeq(X, m, n - 1),
findLongestRepeatingSubSeq(X, m - 1, n));
}
int main()
{
string str = "aabb" ;
int m = str.length();
memset (dp,-1, sizeof (dp));
cout << "The length of the largest subsequence that"
" repeats itself is : "
<< findLongestRepeatingSubSeq(str,m,m);
return 0;
}
|
Java
import java.util.Arrays;
public class GFG {
static int dp[][] = new int [ 1000 ][ 1000 ];
static int findLongestRepeatingSubSeq( char X[], int m, int n) {
if (dp[m][n] != - 1 ) {
return dp[m][n];
}
if (m == 0 || n == 0 ) {
return dp[m][n] = 0 ;
}
if (X[m - 1 ] == X[n - 1 ] && m != n) {
return dp[m][n] = findLongestRepeatingSubSeq(X,
m - 1 , n - 1 ) + 1 ;
}
return dp[m][n] = Math.max(findLongestRepeatingSubSeq(X, m, n - 1 ),
findLongestRepeatingSubSeq(X, m - 1 , n));
}
static public void main(String[] args) {
String str = "aabb" ;
int m = str.length();
for ( int [] row : dp) {
Arrays.fill(row, - 1 );
}
System.out.println( "The length of the largest subsequence that"
+ " repeats itself is : "
+ findLongestRepeatingSubSeq(str.toCharArray(), m, m));
}
}
|
Python3
dp = [[ 0 for i in range ( 1000 )] for j in range ( 1000 )]
def findLongestRepeatingSubSeq( X, m, n):
if (dp[m][n]! = - 1 ):
return dp[m][n]
if (m = = 0 or n = = 0 ):
dp[m][n] = 0
return dp[m][n]
if (X[m - 1 ] = = X[n - 1 ] and m ! = n):
dp[m][n] = findLongestRepeatingSubSeq(X,
m - 1 , n - 1 ) + 1
return dp[m][n]
dp[m][n] = max (findLongestRepeatingSubSeq(X, m, n - 1 ),
findLongestRepeatingSubSeq(X, m - 1 , n))
return dp[m][n]
if __name__ = = "__main__" :
str = "aabb"
m = len ( str )
dp = [[ - 1 for i in range ( 1000 )] for j in range ( 1000 )]
print ( "The length of the largest subsequence that"
" repeats itself is : "
, findLongestRepeatingSubSeq( str ,m,m))
|
C#
using System;
public class GFG {
static int [,]dp = new int [1000,1000];
static int findLongestRepeatingSubSeq( char []X, int m, int n) {
if (dp[m,n] != -1) {
return dp[m,n];
}
if (m == 0 || n == 0) {
return dp[m,n] = 0;
}
if (X[m - 1] == X[n - 1] && m != n) {
return dp[m,n] = findLongestRepeatingSubSeq(X,
m - 1, n - 1) + 1;
}
return dp[m,n] = Math.Max(findLongestRepeatingSubSeq(X, m, n - 1),
findLongestRepeatingSubSeq(X, m - 1, n));
}
static public void Main() {
String str = "aabb" ;
int m = str.Length;
for ( int i = 0; i < dp.GetLength(0); i++)
for ( int j = 0; j < dp.GetLength(1); j++)
dp[i, j] = -1;
Console.WriteLine( "The length of the largest subsequence that"
+ " repeats itself is : "
+ findLongestRepeatingSubSeq(str.ToCharArray(), m, m));
}
}
|
PHP
<?php
$dp = array_fill (0, 1000, array_fill (0, 1000, -1));
function findLongestRepeatingSubSeq( $X , $m , $n )
{
global $dp ;
if ( $dp [ $m ][ $n ] != -1)
return $dp [ $m ][ $n ];
if ( $m == 0 || $n == 0)
return $dp [ $m ][ $n ] = 0;
if ( $X [ $m - 1] == $X [ $n - 1] && $m != $n )
return $dp [ $m ][ $n ] = findLongestRepeatingSubSeq( $X ,
$m - 1, $n - 1) + 1;
return $dp [ $m ][ $n ] = max (findLongestRepeatingSubSeq( $X , $m , $n - 1),
findLongestRepeatingSubSeq( $X , $m - 1, $n ));
}
$str = "aabb" ;
$m = strlen ( $str );
echo "The length of the largest subsequence" .
"that repeats itself is : " .findLongestRepeatingSubSeq( $str , $m , $m );
?>
|
Javascript
<script>
let dp= new Array(1000);
for (let i=0;i<1000;i++)
{
dp[i]= new Array(1000);
for (let j=0;j<1000;j++)
{
dp[i][j]=-1;
}
}
function findLongestRepeatingSubSeq(X,m,n)
{
if (dp[m][n] != -1) {
return dp[m][n];
}
if (m == 0 || n == 0) {
return dp[m][n] = 0;
}
if (X[m - 1] == X[n - 1] && m != n) {
return dp[m][n] = findLongestRepeatingSubSeq(X,
m - 1, n - 1) + 1;
}
return dp[m][n] = Math.max(findLongestRepeatingSubSeq(X, m, n - 1),
findLongestRepeatingSubSeq(X, m - 1, n));
}
let str = "aabb" ;
let m = str.length;
document.write( "The length of the largest subsequence that"
+ " repeats itself is : "
+ findLongestRepeatingSubSeq(str.split( "" ), m, m));
</script>
|
Output
The length of the largest subsequence that repeats itself is : 2
Time Complexity: O(m*n)
Auxiliary Space: O(m*n)
Method 3:
To find the length of the Longest Repeating Subsequence dynamic programming Top-down Approach:
- Take the input string.
- Perform the Longest common subsequence where s1[i]==s1[j] and i!=j.
- Return the length.
C++
#include <bits/stdc++.h>
using namespace std;
int lrs(string s1, int i, int j, vector<vector< int >>&dp){
if (i >= s1.length() || j >= s1.length())
return 0;
if (dp[i][j] != -1)
return dp[i][j];
if (dp[i][j] == -1){
if (s1[i] == s1[j] && i != j)
dp[i][j] = 1+lrs(s1, i+1, j+1, dp);
else
dp[i][j] = max(lrs(s1, i, j+1, dp),
lrs(s1, i+1, j, dp));
}
return dp[i][j];
}
int main(){
string s1 = "aabb" ;
string s2 = s1;
reverse(s2.begin(),s2.end());
vector<vector< int >>dp(1000,vector< int >(1000,-1));
cout<< "LENGTH OF LONGEST REPEATING SUBSEQUENCE IS : " <<lrs(s1, 0, 0, dp);
}
|
Java
import java.lang.*;
import java.io.*;
import java.util.*;
class GFG
{
static int lrs(StringBuilder s1, int i, int j, int [][] dp)
{
if (i >= s1.length() || j >= s1.length())
{
return 0 ;
}
if (dp[i][j] != - 1 )
{
return dp[i][j];
}
if (dp[i][j] == - 1 )
{
if (s1.charAt(i) == s1.charAt(j) && i != j)
{
dp[i][j] = 1 + lrs(s1, i + 1 , j + 1 , dp);
}
else
{
dp[i][j] = Math.max(lrs(s1, i, j + 1 , dp), lrs(s1, i + 1 , j, dp));
}
}
return dp[i][j];
}
public static void main (String[] args)
{
String s1 = "aabb" ;
StringBuilder input1 = new StringBuilder();
input1.append(s1);
input1.reverse();
int [][] dp = new int [ 1000 ][ 1000 ];
for ( int [] row : dp)
{
Arrays.fill(row, - 1 );
}
System.out.println( "LENGTH OF LONGEST REPEATING SUBSEQUENCE IS :" +
lrs(input1, 0 , 0 , dp));
}
}
|
Python3
def lrs(s1, i, j, dp):
if i > = len (s1) or j > = len (s1):
return 0
if dp[i][j] ! = - 1 :
return dp[i][j]
if dp[i][j] = = - 1 :
if s1[i] = = s1[j] and i ! = j:
dp[i][j] = 1 + lrs(s1, i + 1 , j + 1 , dp)
else :
dp[i][j] = max (lrs(s1, i, j + 1 , dp),
lrs(s1, i + 1 , j, dp))
return dp[i][j]
if __name__ = = "__main__" :
s1 = "aabb"
s2 = s1[:: - 1 ]
dp = [[ - 1 for i in range ( 1000 )] for j in range ( 1000 )]
print ( "LENGTH OF LONGEST REPEATING SUBSEQUENCE IS :" ,
lrs(s1, 0 , 0 , dp))
|
C#
using System;
public class GFG{
static int lrs( string s1, int i, int j, int [,] dp)
{
if (i >= s1.Length || j >= s1.Length)
{
return 0;
}
if (dp[i, j] != -1)
{
return dp[i, j];
}
if (dp[i, j] == -1)
{
if (s1[i] == s1[j] && i != j)
{
dp[i, j] = 1 + lrs(s1, i + 1, j + 1, dp);
}
else
{
dp[i, j] = Math.Max(lrs(s1, i, j + 1, dp), lrs(s1, i + 1, j, dp));
}
}
return dp[i, j];
}
static public void Main (){
string s1 = "aabb" ;
char [] chars = s1.ToCharArray();
Array.Reverse(chars);
s1= new String(chars);
int [,] dp = new int [1000,1000];
for ( int i = 0; i < 1000; i++)
{
for ( int j = 0; j < 1000; j++)
{
dp[i, j] = -1;
}
}
Console.WriteLine( "LENGTH OF LONGEST REPEATING SUBSEQUENCE IS :" +
lrs(s1, 0, 0, dp));
}
}
|
Javascript
<script>
function lrs(s1, i, j, dp)
{
if (i >= s1.length || j >= s1.length)
{
return 0;
}
if (dp[i][j] != -1)
{
return dp[i][j];
}
if (dp[i][j] == -1)
{
if (s1[i] == s1[j] && i != j)
{
dp[i][j] = 1 + lrs(s1, i + 1,
j + 1, dp);
}
else
{
dp[i][j] = Math.max(lrs(s1, i, j + 1, dp),
lrs(s1, i + 1, j, dp));
}
}
return dp[i][j];
}
let s1 = "aabb" ;
let input1 = s1.split( "" );
input1.reverse();
let dp = new Array(1000);
for (let i = 0; i < 1000; i++)
{
dp[i] = new Array(1000);
for (let j = 0; j < 1000; j++)
{
dp[i][j] = -1;
}
}
document.write( "LENGTH OF LONGEST REPEATING " +
"SUBSEQUENCE IS :" +
lrs(input1, 0, 0, dp));
</script>
|
Output
LENGTH OF LONGEST REPEATING SUBSEQUENCE IS : 2
Time Complexity: O(n2)
Auxiliary Space: O(n2)
Method 4: If we look closely at solution 1, we can analyze that we are using only the previous column and element just above the current element.
C++
#include <bits/stdc++.h>
using namespace std;
int findLongestRepeatingSubSeq(string str)
{
int n = str.length();
int dp[n+1] = {0};
for ( int i=1; i<=n; i++)
{
int new_a[n+1] = {0};
for ( int j=1; j<=n; j++)
{
if (str[i-1] == str[j-1] && i != j)
{
new_a[j] = 1 + dp[j-1];
}
else
{
new_a[j] = max(dp[j], new_a[j-1]);
}
}
for ( int j=0; j<=n; j++)
dp[j] = new_a[j];
}
return dp[n];
}
int main()
{
string str = "aabb" ;
cout << "The length of the largest subsequence that"
<< " repeats itself is : "
<< findLongestRepeatingSubSeq(str);
return 0;
}
|
Java
import java.util.*;
class GFG {
static int findLongestRepeatingSubSeq(String str)
{
int n = str.length();
int [][] dp = new int [n + 1 ][n + 1 ];
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]);
}
}
}
return dp[n][n];
}
public static void main(String[] args)
{
String str = "aabb" ;
System.out.println( "The length of the largest subsequence that "
+ "repeats itself is : " +
findLongestRepeatingSubSeq(str));
}
}
|
Python3
def findLongestRepeatingSubSeq( str ):
n = len ( str )
dp = [ 0 for i in range (n + 1 )]
for i in range ( 1 , n + 1 ):
new_a = [ 0 ]
for j in range ( 1 , n + 1 ):
if str [i - 1 ] = = str [j - 1 ] and i ! = j:
new_a.append( 1 + dp[j - 1 ])
else :
new_a.append( max (dp[j], new_a[ - 1 ]))
dp = new_a[:]
return dp[ - 1 ]
if __name__ = = '__main__' :
str = "aabb"
print ( "The length of the largest subsequence that repeats itself is : " , findLongestRepeatingSubSeq( str ))
|
C#
using System;
namespace findLongestRepeatingSubSeq {
class GFG {
static int findLongestRepeatingSubSeq( string str)
{
int n = str.Length;
int [] dp = new int [n + 1];
for ( int i = 1; i <= n; i++) {
int [] new_a = new int [n + 1];
for ( int j = 1; j <= n; j++) {
if (str[i - 1] == str[j - 1] && i != j) {
new_a[j] = 1 + dp[j - 1];
}
else {
new_a[j]
= Math.Max(dp[j], new_a[j - 1]);
}
}
for ( int j = 0; j <= n; j++)
dp[j] = new_a[j];
}
return dp[n];
}
static void Main( string [] args)
{
string str = "aabb" ;
Console.WriteLine(
"The length of the largest subsequence that"
+ " repeats itself is : "
+ findLongestRepeatingSubSeq(str));
}
}
}
|
Javascript
function findLongestRepeatingSubSeq( str)
{
let n = str.length;
let dp= new Array(n+1).fill(0);
for (let i=1; i<=n; i++)
{
let new_a= new Array(n+1).fill(0);
for (let j=1; j<=n; j++)
{
if (str[i-1] == str[j-1] && i != j)
{
new_a[j] = 1 + dp[j-1];
}
else
{
new_a[j] = Math.max(dp[j], new_a[j-1]);
}
}
for (let j=0; j<=n; j++)
dp[j] = new_a[j];
}
return dp[n];
}
let str = "aabb" ;
console.log( "The length of the largest subsequence that"
+ " repeats itself is : " + findLongestRepeatingSubSeq(str));
|
Output
The length of the largest subsequence that repeats itself is : 2
Time Complexity: O(n2)
Auxiliary Space: O(n)
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
17 Feb, 2023
Like Article
Save Article