Skip to content
Related Articles
Open in App
Not now

Related Articles

Length of minimized Compressed String

Improve Article
Save Article
  • Difficulty Level : Hard
  • Last Updated : 13 Jun, 2022
Improve Article
Save Article

Given a string S, the task is to find the length of the shortest compressed string. The string can be compressed in the following way:

  • If S = “ABCDABCD”, then the string can be compressed as (ABCD)2, so the length of the compressed string will be 4.
  • If S = “AABBCCDD” then the string compressed form will be A2B2C2D2 therefore, the length of the compressed string will be 4.

Examples:

Input: S = “aaba”
Output: 3
Explanation : It can be rewritten as a2ba therefore the answer will be 3.

Input: S = “aaabaaabccdaaabaaabccd”
Output: 4
Explanation: The string can be rewritten as (((a)3b)2(c)2d)2. Therefore, the answer will be 4.
 

Approach: The problem can be solved using dynamic programming because it has Optimal Substructure and Overlapping Subproblems. Follow the steps below to solve the problem:

  • Initialize a dp[][] vector, where dp[i][j] stores the length of compressed substring s[i], s[i+1], …, s[j].
  • Iterate in the range [1, N] using the variable l and perform the following steps: 
    • Iterate in the range [0, N-l] using the variable i and perform the following steps:
      • Initialize a variable say, j as i+l-1. 
      • If i is equal to j, then update dp[i][j] as 1 and continue.
      • Iterate in the range [i, j-1] using the variable k and update dp[i][j] as min of dp[i][j] and dp[i][k] + dp[k][j].
      • Initialize a variable say, temp as s.substr(i, l).
      • Then, find the longest prefix that is also the suffix of the substring temp.
      • If the substring is of the form of dp[i][k]^n(l%(l – pref[l-1]) = 0), then update the value of dp[i][j] as min(dp[i][j], dp[i][i + (l-pref[l-1] – 1)]).
  • Finally, print the value of dp[0][N-1] as the answer.

Below is the implementation of the above approach: 

C++




// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Prefix function to calculate
// longest prefix that is also
// the suffix of the substring S
vector<int> prefix_function(string s)
{
 
    int n = (int)s.length();
 
    vector<int> pi(n);
 
    for (int i = 1; i < n; i++) {
 
        int j = pi[i - 1];
 
        while (j > 0 && s[i] != s[j])
            j = pi[j - 1];
        if (s[i] == s[j])
            j++;
        pi[i] = j;
    }
 
    return pi;
}
 
// Function to find the length of the
// shortest compressed string
void minLength(string s, int n)
{
    // Declare a 2D dp vector
    vector<vector<int> > dp(n + 1, vector<int>(n + 1, 10000));
 
    // Traversing substring on the basis of length
    for (int l = 1; l <= n; l++) {
        // For loop for each substring of length l
        for (int i = 0; i < n - l + 1; i++) {
            // Second substring coordinate
            int j = i + l - 1;
 
            // If the length of the string is 1
            // then dp[i][j] = 1
            if (i == j) {
                dp[i][j] = 1;
                continue;
            }
 
            // Finding smallest dp[i][j] value
            // by breaking it in two substrings
            for (int k = i; k < j; k++) {
                dp[i][j] = min(dp[i][j],
                               dp[i][k] + dp[k + 1][j]);
            }
 
            // Substring starting with i of length L
            string temp = s.substr(i, l);
 
            // Prefix function of the substring temp
            auto pref = prefix_function(temp);
 
            // Checking if the substring is
            // of the form of dp[i][k]^n
            if (l % (l - pref[l - 1]) == 0) {
                // If yes, check if dp[i][k] is
                // less than dp[i][j]
                dp[i][j] = min(dp[i][j],
                               dp[i][i + (l - pref[l - 1] - 1)]);
            }
        }
    }
 
    // Finally, print the required answer
    cout << dp[0][n - 1] << endl;
}
 
// Driver Code
int main()
{
    // Given Input
    int n = 4;
    string s = "aaba";
 
    // Function Call
    minLength(s, n);
}

Java




/*package whatever //do not write package name here */
import java.io.*;
import java.util.*;
 
class GFG {
  // Java program for the above approach
 
  // Prefix function to calculate
  // longest prefix that is also
  // the suffix of the substring S
  static int[] prefix_function(String s)
  {
 
    int n = s.length();
 
    int[] pi = new int[n];
 
    for (int i = 1; i < n; i++) {
 
      int j = pi[i - 1];
 
      while (j > 0 && s.charAt(i) != s.charAt(j))
        j = pi[j - 1];
      if (s.charAt(i) == s.charAt(j))
        j++;
      pi[i] = j;
    }
 
    return pi;
  }
 
  // Function to find the length of the
  // shortest compressed string
  static void minLength(String s, int n)
  {
    // Declare a 2D dp vector
    int dp[][] = new int[n + 1][n + 1];
    for(int[] row : dp){
      Arrays.fill(row, 10000);
    }
 
    // Traversing substring on the basis of length
    for (int l = 1; l <= n; l++) {
      // For loop for each substring of length l
      for (int i = 0; i < n - l + 1; i++) {
        // Second substring coordinate
        int j = i + l - 1;
 
        // If the length of the string is 1
        // then dp[i][j] = 1
        if (i == j) {
          dp[i][j] = 1;
          continue;
        }
 
        // Finding smallest dp[i][j] value
        // by breaking it in two substrings
        for (int k = i; k < j; k++) {
          dp[i][j] = Math.min(dp[i][j],
                              dp[i][k] + dp[k + 1][j]);
        }
 
        // Substring starting with i of length L
        String temp = s.substring(i, i+l);
 
        // Prefix function of the substring temp
        int[] pref = prefix_function(temp);
 
        // Checking if the substring is
        // of the form of dp[i][k]^n
        if (l % (l - pref[l - 1]) == 0) {
          // If yes, check if dp[i][k] is
          // less than dp[i][j]
          dp[i][j] = Math.min(dp[i][j],
                              dp[i][i + (l - pref[l - 1] - 1)]);
        }
      }
    }
 
    // Finally, print the required answer
    System.out.println(dp[0][n - 1]);
  }
 
  // Driver Code
  public static void main(String args[])
  {
    // Given Input
    int n = 4;
    String s = "aaba";
 
    // Function Call
    minLength(s, n);
  }
}
 
// This code is contributed by shinjanpatra

Python3




# Python program for the above approach
 
# Prefix function to calculate
# longest prefix that is also
# the suffix of the substring S
def prefix_function(s):
 
    n = len(s)
 
    pi = [0 for i in range(n)]
 
    for i in range(1,n):
 
        j = pi[i - 1]
 
        while (j > 0 and s[i] != s[j]):
            j = pi[j - 1]
        if (s[i] == s[j]):
            j += 1
        pi[i] = j
 
    return pi
 
# Function to find the length of the
# shortest compressed string
def minLength(s,n):
 
    # Declare a 2D dp vector
    dp = [[10000 for col in range(n+1)] for row in range(n + 1)]
 
    # Traversing substring on the basis of length
    for l in range(1,n+1):
        # For loop for each substring of length l
        for i in range(n - l + 1):
            # Second substring coordinate
            j = i + l - 1
 
            # If the length of the string is 1
            # then dp[i][j] = 1
            if (i == j):
                dp[i][j] = 1
                continue
 
            # Finding smallest dp[i][j] value
            # by breaking it in two substrings
            for k in range(i,j):
                dp[i][j] = min(dp[i][j],dp[i][k] + dp[k + 1][j])
 
            # Substring starting with i of length L
            temp = s[i:i+l]
 
            # Prefix function of the substring temp
            pref = prefix_function(temp)
 
            # Checking if the substring is
            # of the form of dp[i][k]^n
            if (l % (l - pref[l - 1]) == 0):
                # If yes, check if dp[i][k] is
                # less than dp[i][j]
                dp[i][j] = min(dp[i][j],dp[i][i + (l - pref[l - 1] - 1)])
 
    # Finally, print the required answer
    print(dp[0][n - 1])
 
# Driver Code
 
# Given Input
n = 4
s = "aaba"
 
# Function Call
minLength(s, n)
 
# This code is contributed by shinjanpatra

C#




// C# program to implement above approach
using System;
using System.Collections.Generic;
 
class GFG
{
   
  // Prefix function to calculate
  // longest prefix that is also
  // the suffix of the substring S
  static int[] prefix_function(String s)
  {
 
    int n = s.Length;
 
    int[] pi = new int[n];
 
    for (int i = 1 ; i < n ; i++) {
 
      int j = pi[i - 1];
 
      while (j > 0 && s[i] != s[j]){
        j = pi[j - 1];
      }
      if (s[i] == s[j]){
        j++;
      }
      pi[i] = j;
    }
 
    return pi;
  }
 
  // Function to find the length of the
  // shortest compressed string
  static void minLength(String s, int n)
  {
    // Declare a 2D dp vector
    int[][] dp = new int[n + 1][];
    for(int i = 0 ; i <= n ; i++){
      dp[i] = new int[n+1];
    }
 
    foreach(int[] row in dp){
      for(int i = 0 ; i < row.Length ; i++){
        row[i] = 10000;
      }
    }
 
    // Traversing substring on the basis of length
    for (int l = 1 ; l <= n ; l++) {
      // For loop for each substring of length l
      for (int i = 0; i < n - l + 1; i++) {
        // Second substring coordinate
        int j = i + l - 1;
 
        // If the length of the string is 1
        // then dp[i][j] = 1
        if (i == j) {
          dp[i][j] = 1;
          continue;
        }
 
        // Finding smallest dp[i][j] value
        // by breaking it in two substrings
        for (int k = i; k < j; k++) {
          dp[i][j] = Math.Min(dp[i][j], dp[i][k] + dp[k + 1][j]);
        }
 
        // Substring starting with i of length L
        String temp = s.Substring(i, l);
 
        // Prefix function of the substring temp
        int[] pref = prefix_function(temp);
 
        // Checking if the substring is
        // of the form of dp[i][k]^n
        if (l % (l - pref[l - 1]) == 0) {
          // If yes, check if dp[i][k] is
          // less than dp[i][j]
          dp[i][j] = Math.Min(dp[i][j], dp[i][i + (l - pref[l - 1] - 1)]);
        }
      }
    }
 
    // Finally, print the required answer
    Console.Write(dp[0][n - 1]);
  }
 
  // Driver Code
  public static void Main(string[] args){
 
    int n = 4;
    String s = "aaba";
 
    // Function Call
    minLength(s, n);
 
  }
}
 
// This code is contributed by subhamgoyal2014.

Javascript




<script>
 
// JavaScript program for the above approach
 
// Prefix function to calculate
// longest prefix that is also
// the suffix of the substring S
function prefix_function(s)
{
 
    let n = s.length;
    let pi = new Array(n).fill(0);
 
    for (let i = 1; i < n; i++)
    {
        let j = pi[i - 1];
        while (j > 0 && s[i] != s[j])
            j = pi[j - 1];
        if (s[i] == s[j])
            j++;
        pi[i] = j;
    }
 
    return pi;
}
 
// Function to find the length of the
// shortest compressed string
function minLength(s, n)
{
 
    // Declare a 2D dp vector
    let dp = new Array(n + 1).fill(10000).map(()=>new Array(n + 1).fill(10000));
 
    // Traversing substring on the basis of length
    for (let l = 1; l <= n; l++)
    {
     
        // For loop for each substring of length l
        for (let i = 0; i < n - l + 1; i++)
        {
         
            // Second substring coordinate
            let j = i + l - 1;
 
            // If the length of the string is 1
            // then dp[i][j] = 1
            if (i == j) {
                dp[i][j] = 1;
                continue;
            }
 
            // Finding smallest dp[i][j] value
            // by breaking it in two substrings
            for (let k = i; k < j; k++) {
                dp[i][j] = Math.min(dp[i][j],dp[i][k] + dp[k + 1][j]);
            }
 
            // Substring starting with i of length L
            let temp = s.substring(i, i+l);
 
            // Prefix function of the substring temp
            let pref = prefix_function(temp);
 
            // Checking if the substring is
            // of the form of dp[i][k]^n
            if (l % (l - pref[l - 1]) == 0)
            {
             
                // If yes, check if dp[i][k] is
                // less than dp[i][j]
                dp[i][j] = Math.min(dp[i][j],
                               dp[i][i + (l - pref[l - 1] - 1)]);
            }
        }
    }
 
    // Finally, print the required answer
    document.write(dp[0][n - 1],"</br>");
}
 
// Driver Code
 
// Given Input
let n = 4;
let s = "aaba";
 
// Function Call
minLength(s, n);
 
// This code is contributed by shinjanpatra
 
</script>

Output:

3

Time Complexity: O(N^3)
Auxiliary Space: O(N^2)


My Personal Notes arrow_drop_up
Related Articles

Start Your Coding Journey Now!