# Maximum number of given operations to remove the entire string

• Difficulty Level : Hard
• Last Updated : 07 Feb, 2023

Given string str containing lowercase English characters, we can perform the following two operations on the given string:

1. Remove the entire string.
2. Remove a prefix of the string str[0…i] only if it is equal to the sub-string str[(i + 1)…(2 * i + 1)].

The task is to find the maximum number of operations required to delete the entire string.

Examples:

Input: str = “abababab”
Output:
Explanation:
Operation 1: Delete prefix “ab” and the string becomes “ababab”.
Operation 2: Delete prefix “ab” and the string becomes “abab”.
Operation 3: Delete prefix “ab”, str = “ab”.
Operation 4: Delete the entire string.

Input: s = “abc”
Output:

## Approach using KMP + Dynamic programming:

The idea is to store all possible length deletion of 2nd operation for every index of the given string and explore every possible deletion on each index and return the maximum operation among them.

Follow the step below to implement the above idea:

• Iterate over all the indexes and find What are the possible deletions using 2nd operation that can be performed starting at index i.
• Use KMP algorithm to find all such possible deletions.
• If LPS (longest common prefix which is also a suffix) ending at i  satisfy the condition that the length of substring ending at i is double the length of LPS at i, then this is a possible jump and store it into some array.
• Iterate over each index and go for every possible length of deletion at index i and maximize the result.

Below is the implementation of the above approach:

## C++

 `// C++ implementation of the approach``#include ``using` `namespace` `std;` `// For storing all possible length deletion at index i``vector > arr;` `// For memoization``vector<``int``> dp;` `// Use modified KMP to find valid deletion``vector<``int``> KMP(string& s)``{``    ``int` `n = s.size();``    ``vector<``int``> pi(n);` `    ``for` `(``int` `i = 1; i < n; i++) {``        ``int` `j = pi[i - 1];` `        ``if` `(s[i] == s[j]) {``            ``pi[i] = j + 1;``        ``}``        ``else` `{``            ``while` `(j > 0 && s[i] != s[j]) {``                ``j = pi[j - 1];``            ``}` `            ``if` `(s[i] == s[j]) {``                ``pi[i] = j + 1;``            ``}``            ``else` `{``                ``pi[i] = 0;``            ``}``        ``}``    ``}` `    ``// Store all possible length deletion``    ``// which follow the given condition that``    ``// Remove a prefix of the string str[0â€¦i]``    ``// only if it is equal to the sub-string``    ``// str[(i + 1)â€¦(2 * i + 1)].``    ``vector<``int``> res;` `    ``for` `(``int` `i = 0; i < n; i++) {``        ``if` `(i + 1 - pi[i] == pi[i]) {``            ``res.push_back(pi[i]);``        ``}``    ``}` `    ``return` `res;``}` `// Function to find all maximum possible deletion``int` `solve(``int` `i, ``int` `n)``{``    ``if` `(i >= n)``        ``return` `0;``    ``if` `(arr[i].size() == 0)``        ``return` `1;` `    ``if` `(dp[i] != -1)``        ``return` `dp[i];` `    ``int` `res = 0;` `    ``// Iterate over each index and go for ever possible``    ``// length of deletion at index i``    ``for` `(``int` `jump : arr[i]) {``        ``res = max(res, 1 + solve(i + jump, n));``    ``}` `    ``// Store the maximum possible deletion``    ``// at index i into res and return the res.``    ``return` `dp[i] = res;``}` `int` `deleteString(string s)``{``    ``int` `n = s.size();``    ``dp.resize(n + 1, -1);` `    ``// Iterate over all the index and find``    ``// What are the possible deletion that can be``    ``// Perform starting from index i``    ``for` `(``int` `i = 0; i < n; i++) {``        ``string sub = s.substr(i);``        ``arr.push_back(KMP(sub));``    ``}` `    ``// Function call for finding the maximum deletion``    ``// operation required``    ``return` `solve(0, n);``}` `// Driver code``int` `main()``{``    ``// Input string``    ``string s = ``"abababab"``;` `    ``// Function call``    ``cout << deleteString(s);` `    ``return` `0;``}`

## Java

 `// Java implementation of the approach``import` `java.io.*;``import` `java.util.*;` `class` `GFG {``    ``// Use modified KMP to find valid deletion``    ``public` `static` `List KMP(StringBuilder s)``    ``{``        ``int` `n = s.length();``        ``Integer[] temp = ``new` `Integer[n];``        ``Arrays.fill(temp, ``0``);``        ``List pi = Arrays.asList(temp);` `        ``for` `(``int` `i = ``1``; i < n; i++) {``            ``int` `j = pi.get(i - ``1``);` `            ``if` `(s.charAt(i) == s.charAt(j)) {``                ``pi.set(i, j + ``1``);``            ``}``            ``else` `{``                ``while` `(j > ``0``                       ``&& s.charAt(i) != s.charAt(j)) {``                    ``j = pi.get(j - ``1``);``                ``}` `                ``if` `(s.charAt(i) == s.charAt(j)) {``                    ``pi.set(i, j + ``1``);``                ``}``                ``else` `{``                    ``pi.set(i, ``0``);``                ``}``            ``}``        ``}` `        ``// Store all possible length deletion``        ``// which follow the given condition that``        ``// Remove a prefix of the string str[0â€¦i]``        ``// only if it is equal to the sub-string``        ``// str[(i + 1)â€¦(2 * i + 1)].``        ``List res = ``new` `ArrayList();` `        ``for` `(``int` `i = ``0``; i < n; i++) {``            ``if` `(i + ``1` `- pi.get(i) == pi.get(i)) {``                ``res.add(pi.get(i));``            ``}``        ``}` `        ``return` `res;``    ``}` `    ``// Function to find all maximum possible deletion``    ``public` `static` `int` `solve(``int` `i, ``int` `n, ``int``[] dp,``                            ``List > arr)``    ``{``        ``if` `(i >= n)``            ``return` `0``;``        ``if` `(arr.get(i).size() == ``0``)``            ``return` `1``;` `        ``if` `(dp[i] != -``1``)``            ``return` `dp[i];` `        ``int` `res = ``0``;` `        ``// Iterate over each index and go for ever possible``        ``// length of deletion at index i``        ``for` `(``int` `jump : arr.get(i)) {``            ``res = Math.max(res,``                           ``1` `+ solve(i + jump, n, dp, arr));``        ``}` `        ``// Store the maximum possible deletion``        ``// at index i into res and return the res.``        ``return` `dp[i] = res;``    ``}` `    ``public` `static` `int` `deleteString(StringBuilder s,``                                   ``List > arr)``    ``{``        ``int` `n = s.length();` `        ``int``[] dp = ``new` `int``[n + ``1``];` `        ``// For memoization``        ``Arrays.fill(dp, -``1``);` `        ``// Iterate over all the index and find``        ``// What are the possible deletion that can be``        ``// Perform starting from index i``        ``for` `(``int` `i = ``0``; i < n; i++) {``            ``StringBuilder sub``                ``= ``new` `StringBuilder(s.substring(i));``            ``arr.add(KMP(sub));``        ``}` `        ``// Function call for finding the maximum deletion``        ``// operation required``        ``return` `solve(``0``, n, dp, arr);``    ``}` `    ``public` `static` `void` `main(String[] args)``    ``{``        ``StringBuilder s = ``new` `StringBuilder(``"abababab"``);` `        ``// For storing all possible length deletion at index``        ``// i``        ``List > arr``            ``= ``new` `ArrayList >();` `        ``// Function call``        ``System.out.println(deleteString(s, arr));``    ``}``}`

## Python3

 `# Python implementation of the approach` `# For storing all possible length deletion at index i``arr``=``[];` `# For memoization``dp``=``[];` `# Use modified KMP to find valid deletion``def` `KMP( s):``    ``n ``=` `len``(s);``    ``pi``=``[``0``]``*``n;` `    ``for` `i ``in` `range``(``1``,n):``        ``j ``=` `pi[i ``-` `1``];` `        ``if` `(s[i] ``=``=` `s[j]) :``            ``pi[i] ``=` `j ``+` `1``;``        ` `        ``else` `:``            ``while` `(j > ``0` `and` `s[i] !``=` `s[j]) :``                ``j ``=` `pi[j ``-` `1``];``            `  `            ``if` `(s[i] ``=``=` `s[j]):``                ``pi[i] ``=` `j ``+` `1``;``            ` `            ``else` `:``                ``pi[i] ``=` `0``;``            ` `        ` `    `  `    ``# Store all possible length deletion``    ``# which follow the given condition that``    ``# Remove a prefix of the string str[0â€¦i]``    ``# only if it is equal to the sub-string``    ``# str[(i + 1)â€¦(2 * i + 1)].``    ``res``=``[];` `    ``for` `i ``in` `range``(``0``,n):``        ``if` `(i ``+` `1` `-` `pi[i] ``=``=` `pi[i]) :``            ``res.append(pi[i]);``            ` `    ``return` `res;`  `# Function to find all maximum possible deletion``def` `solve( i,  n):` `    ``if` `(i >``=` `n):``        ``return` `0``;``    ``if` `(``len``(arr[i]) ``=``=` `0``):``        ``return` `1``;` `    ``if` `(dp[i] !``=` `-``1``):``        ``return` `dp[i];` `    ``res ``=` `0``;` `    ``# Iterate over each index and go for ever possible``    ``# length of deletion at index i``    ``for` `jump ``in` `arr[i]:``        ``res ``=` `max``(res, ``1` `+` `solve(i ``+` `jump, n));``    `  `    ``# Store the maximum possible deletion``    ``# at index i into res and return the res.``    ``dp[i]``=``res;``    ``return` `dp[i];`  `def` `deleteString( s):``    ``n ``=` `len``(s);``    ``for` `i ``in` `range``(``0``,n``+``1``):``        ``dp.append(``-``1``);` `    ``# Iterate over all the index and find``    ``# What are the possible deletion that can be``    ``# Perform starting from index i``    ``for` `i ``in` `range``(``0``,n):``        ``sub ``=` `s[i:n];``        ``arr.append(KMP(sub));``    `  `    ``# Function call for finding the maximum deletion``    ``# operation required``    ``return` `solve(``0``, n);`  `# Driver code``# Input string``s ``=` `"abababab"``;` `# Function call``print``(deleteString(s));` `# this code is contributed by poojaagarwal2.`

## C#

 `// C# implementation of the approach``using` `System;``using` `System.Collections.Generic;` `class` `GFG {``    ``// Use modified KMP to find valid deletion``    ``public` `static` `List<``int``> KMP(``string` `s)``    ``{``        ``int` `n = s.Length;``        ``int``[] temp = ``new` `int``[n];``        ``for` `(``int` `i = 0; i < n; i++) {``            ``temp[i] = 0;``        ``}``        ``List<``int``> pi = ``new` `List<``int``>(temp);` `        ``for` `(``int` `i = 1; i < n; i++) {``            ``int` `j = pi[i - 1];` `            ``if` `(s[i] == s[j]) {``                ``pi[i] = j + 1;``            ``}``            ``else` `{``                ``while` `(j > 0 && s[i] != s[j]) {``                    ``j = pi[j - 1];``                ``}` `                ``if` `(s[i] == s[j]) {``                    ``pi[i] = j + 1;``                ``}``                ``else` `{``                    ``pi[i] = 0;``                ``}``            ``}``        ``}` `        ``// Store all possible length deletion``        ``// which follow the given condition that``        ``// Remove a prefix of the string str[0â€¦i]``        ``// only if it is equal to the sub-string``        ``// str[(i + 1)â€¦(2 * i + 1)].``        ``List<``int``> res = ``new` `List<``int``>();` `        ``for` `(``int` `i = 0; i < n; i++) {``            ``if` `(i + 1 - pi[i] == pi[i]) {``                ``res.Add(pi[i]);``            ``}``        ``}` `        ``return` `res;``    ``}` `    ``// Function to find all maximum possible deletion``    ``public` `static` `int` `solve(``int` `i, ``int` `n, ``int``[] dp,``                            ``List > arr)``    ``{``        ``if` `(i >= n)``            ``return` `0;``        ``if` `(arr[i].Count == 0)``            ``return` `1;` `        ``if` `(dp[i] != -1)``            ``return` `dp[i];` `        ``int` `res = 0;` `        ``// Iterate over each index and go for ever possible``        ``// length of deletion at index i``        ``foreach` `(``int` `jump ``in` `arr[i]) {``            ``res = Math.Max(res,``                           ``1 + solve(i + jump, n, dp, arr));``        ``}` `        ``// Store the maximum possible deletion``        ``// at index i into res and return the res.``        ``return` `dp[i] = res;``    ``}` `    ``public` `static` `int` `deleteString(``string` `s,``                                   ``List > arr)``    ``{``        ``int` `n = s.Length;` `        ``int``[] dp = ``new` `int``[n + 1];` `        ``// For memoization``        ``for` `(``int` `i = 0; i < n + 1; i++) {``            ``dp[i] = -1;``        ``}` `        ``// Iterate over all the index and find``        ``// What are the possible deletion that can be``        ``// Perform starting from index i``        ``for` `(``int` `i = 0; i < n; i++) {``            ``string` `sub``                ``= s.Substring(i);``            ``arr.Add(KMP(sub));``        ``}``        ``// Function call for finding the maximum deletion``        ``// operation required``        ``return` `solve(0, n, dp, arr);``    ``}` `    ``public` `static` `void` `Main(``string``[] args)``    ``{``        ``string` `s =``"abababab"``;` `        ``// For storing all possible length deletion at index``        ``// i``        ``var` `arr = ``new` `List >();` `        ``// Function call``        ``Console.WriteLine(deleteString(s, arr));``    ``}``}``//This code is contributed by ik_9`

## Javascript

 `// JavaScript implementation of the approach` `// Use modified KMP to find valid deletion``function` `KMP(s) {``let n = s.length;``let pi = ``new` `Array(n);` `for` `(let i = 1; i < n; i++) {``let j = pi[i - 1];``if` `(s[i] === s[j]) {``  ``pi[i] = j + 1;``} ``else` `{``  ``while` `(j > 0 && s[i] !== s[j]) {``j = pi[j - 1];``  ``}` `  ``if` `(s[i] === s[j]) {``pi[i] = j + 1;``  ``} ``else` `{``pi[i] = 0;``  ``}``}``}` `// Store all possible length deletion``// which follow the given condition that``// Remove a prefix of the string str[0â€¦i]``// only if it is equal to the sub-string``// str[(i + 1)â€¦(2 * i + 1)].``let res = [];` `for` `(let i = 0; i < n; i++) {``if` `(i + 1 - pi[i] === pi[i]) {``res.push(pi[i]);``}``}` `return` `res;``}` `// Function to find all maximum possible deletion``function` `solve(i, n, arr, dp) {``if` `(i >= n) ``return` `0;``if` `(arr[i].length === 0) ``return` `1;` `if` `(dp[i] !== -1) ``return` `dp[i];` `let res = 0;` `// Iterate over each index and go for ever possible``// length of deletion at index i``for` `(let jump of arr[i]) {``res = Math.max(res, 1 + solve(i + jump, n, arr, dp));``}``// Store the maximum possible deletion``// at index i into res and return the res.``return` `(dp[i] = res);``}` `function` `deleteString(s) {``let n = s.length;``let dp = Array(n + 1).fill(-1);``let arr = [];` `// Iterate over all the index and find``// What are the possible deletion that can be``// Perform starting from index i``for` `(let i = 0; i < n; i++) {``let sub = s.substring(i);``arr.push(KMP(sub));``}` `// Function call for finding the maximum deletion``// operation required``return` `solve(0, n, arr, dp);``}` `// Driver code` `// Input string``let s = ``"abababab"``;` `// Function call``console.log(deleteString(s));` `// This code is contributed by Aman Kumar.`

Output

`4`

Time Complexity: O(N2)
Auxiliary Space: O(N)

My Personal Notes arrow_drop_up