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 res

s = '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)