Welcome to the daily solutions of our PROBLEM OF THE DAY (POTD). We will discuss the entire problem step-by-step and work towards developing an optimized solution. This will not only help you brush up on your concepts of Dynamic Programming but will also help you build up problem-solving skills.
POTD 27 October: Minimum Deletions
Given a string of S as input. Your task is to write a program to delete the minimum number of characters from the string so that the resultant string is a palindrome.
Note: The order of characters in the string should be maintained.
Example 1:
Input: S = “aebcbda”
Output: 2
Explanation: Remove characters ‘e’ and ‘d’, to make the string S = “abcda”, which is a palindrome.Example 2:
Input: “geeksforgeeks“
Output: 8
Explanation: One of the possible result string can be to make the string S = “eefee”, so answer is 13 – 5 = 8.
Minimum Deletions to make the string palindrome using Dynamic Programming:
The problem is based on the concept of Longest Palindromic Subsequence. If we calculate the length of the longest common subsequence then it means that this is the longest palindromic string which we can construct by deleting minimum number of characters from the string. So, the result will be: (length of string – length of the longest palindromic subsequence)
Below is the implementation of the above approach:
C++
class Solution {
public:
// Returns the length of
// the longest palindromic
// subsequence in 'S'
int lps(string S)
{
int n = S.size();
// Create a table to store
// results of subproblems
int L[n][n];
// Strings of length 1
// are palindrome of length 1
for (int i = 0; i < n; i++)
L[i][i] = 1;
// Build the table. Note that
// the lower diagonal values
// of table are useless and
// not filled in the process.
// c1 is length of substring
for (int cl = 2; cl <= n; cl++) {
for (int i = 0; i < n - cl + 1; i++) {
int j = i + cl - 1;
if (S[i] == S[j] && cl == 2)
L[i][j] = 2;
else if (S[i] == S[j])
L[i][j] = L[i + 1][j - 1] + 2;
else
L[i][j] = max(L[i][j - 1], L[i + 1][j]);
}
}
// length of longest
// palindromic subseq
return L[0][n - 1];
}
int minimumNumberOfDeletions(string S)
{
// code here
int n = S.size();
// Find longest palindromic
// subsequence
int len = lps(S);
// After removing characters
// other than the lps, we
// get palindrome.
return (n - len);
}
};
Java
class Solution {
// Returns the length of
// the longest palindromic
// subsequence in 'S'
static int lps(String S)
{
int n = S.length();
// Create a table to store
// results of subproblems
int L[][] = new int[n][n];
// Strings of length 1
// are palindrome of length 1
for (int i = 0; i < n; i++)
L[i][i] = 1;
// Build the table. Note
// that the lower diagonal
// values of table are useless
// and not filled in the process.
// c1 is length of substring
for (int cl = 2; cl <= n; cl++) {
for (int i = 0; i < n - cl + 1; i++) {
int j = i + cl - 1;
if (S.charAt(i) == S.charAt(j) && cl == 2)
L[i][j] = 2;
else if (S.charAt(i) == S.charAt(j))
L[i][j] = L[i + 1][j - 1] + 2;
else
L[i][j] = Integer.max(L[i][j - 1],
L[i + 1][j]);
}
}
// length of longest
// palindromic subsequence
return L[0][n - 1];
}
static int minimumNumberOfDeletions(String S)
{
// your code here
int n = S.length();
// Find longest palindromic
// subsequence
int len = lps(S);
// After removing characters
// other than the lps, we get
// palindrome.
return (n - len);
}
}
Python3
class Solution:
# Returns the length of
# the longest palindromic
# subsequence in 'S'
def lps(self, S):
n = len(S)
# Create a table to store
# results of subproblems
L = [[0 for x in range(n)]for y in range(n)]
# Strings of length 1
# are palindrome of length 1
for i in range(n):
L[i][i] = 1
# Build the table. Note that
# the lower diagonal values
# of table are useless and
# not filled in the process.
# c1 is length of substring
for cl in range(2, n+1):
for i in range(n - cl + 1):
j = i + cl - 1
if (S[i] == S[j] and cl == 2):
L[i][j] = 2
elif (S[i] == S[j]):
L[i][j] = L[i + 1][j - 1] + 2
else:
L[i][j] = max(L[i][j - 1], L[i + 1][j])
# length of longest
# palindromic subseq
return L[0][n - 1]
def minimumNumberOfDeletions(self, S):
# code here
n = len(S)
# Find longest palindromic
# subsequence
l = self.lps(S)
# After removing characters
# other than the lps, we
# get palindrome.
return (n - l)
Time Complexity: O(n^2), where n is the length of the input string.
Auxiliary Space: O(n^2) as a 2D array of size nxn is used to store the subproblems.
Minimum Deletions to make the string palindrome using Dynamic Programming (Space Optimized):
In the previous approach, the current value L[i][j] only depends upon the current and previous row values of DP. So to optimize the space complexity we use a single 1D array to store the computations.
class Solution {
public :
// Returns the length of
// the longest palindromic
// subsequence in 'S'
int lps(string S)
{
int n = S.size();
// array to store computation
// of subproblems
int L[n];
// iterate over subproblems to get the current
// value from previous computation
for ( int i = n - 1; i >= 0; i--) {
// to store previous values
int back_up = 0;
for ( int j = i; j < n; j++) {
if (j == i)
L[j] = 1;
else if (S[i] == S[j]) {
int temp = L[j];
L[j] = back_up + 2;
back_up = temp;
}
else {
back_up = L[j];
L[j] = max(L[j], L[j - 1]);
}
}
}
// return final answer
return L[n - 1];
}
int minimumNumberOfDeletions(string S)
{
// code here
int n = S.size();
// Find longest palindromic
// subsequence
int len = lps(S);
// After removing characters
// other than the lps, we
// get palindrome.
return (n - len);
}
}; |
class Solution {
// Returns the length of the longest palindromic
// subsequence in 'S'
static int lps(String S)
{
int n = S.length();
// Array to store computation of subproblems
int [] L = new int [n];
// Iterate over subproblems to get the current value
// from previous computation
for ( int i = n - 1 ; i >= 0 ; i--) {
// To store previous values
int back_up = 0 ;
for ( int j = i; j < n; j++) {
if (j == i)
L[j] = 1 ;
else if (S.charAt(i) == S.charAt(j)) {
int temp = L[j];
L[j] = back_up + 2 ;
back_up = temp;
}
else {
back_up = L[j];
L[j] = Math.max(L[j], L[j - 1 ]);
}
}
}
// Return final answer
return L[n - 1 ];
}
static int minimumNumberOfDeletions(String S)
{
// your code here
int n = S.length();
// Find longest palindromic
// subsequence
int len = lps(S);
// After removing characters
// other than the lps, we get
// palindrome.
return (n - len);
}
} |
class Solution:
# Returns the length of
# the longest palindromic
# subsequence in 'S'
def lps( self , S):
n = len (S)
# List to store computation
# of subproblems
L = [ 0 ] * n
# Iterate over subproblems to get the current
# value from previous computation
for i in range (n - 1 , - 1 , - 1 ):
# To store previous values
back_up = 0
for j in range (i, n):
if j = = i:
L[j] = 1
elif S[i] = = S[j]:
temp = L[j]
L[j] = back_up + 2
back_up = temp
else :
back_up = L[j]
L[j] = max (L[j], L[j - 1 ])
# Return final answer
return L[n - 1 ]
def minimumNumberOfDeletions( self , S):
# code here
n = len (S)
# Find longest palindromic
# subsequence
l = self .lps(S)
# After removing characters
# other than the lps, we
# get palindrome.
return (n - l)
|
using System;
class Solution {
// Returns the length of
// the longest palindromic
// subsequence in 'S'
static int Lps( string S)
{
int n = S.Length;
// List to store computation
// of subproblems
int [] L = new int [n];
// Iterate over subproblems to get the current
// value from previous computation
for ( int i = n - 1; i >= 0; i--) {
// To store previous values
int backUp = 0;
for ( int j = i; j < n; j++) {
if (j == i)
L[j] = 1;
else if (S[i] == S[j]) {
int temp = L[j];
L[j] = backUp + 2;
backUp = temp;
}
else {
backUp = L[j];
L[j] = Math.Max(L[j], L[j - 1]);
}
}
}
// Return final answer
return L[n - 1];
}
static int MinimumNumberOfDeletions( string S)
{
int n = S.Length;
// Find longest palindromic
// subsequence
int l = Lps(S);
// After removing characters
// other than the lps, we
// get palindrome.
return (n - l);
}
static void Main()
{
string inputString = "your_input_string_here" ;
// Calculate minimum number of deletions
int result = MinimumNumberOfDeletions(inputString);
// Do not generate any output as per the request
}
} |
class Solution { // Returns the length of the longest palindromic
// subsequence in 'S'
static lps(S) {
const n = S.length;
// Array to store computation of subproblems
const L = new Array(n);
// Iterate over subproblems to get the current value
// from previous computation
for (let i = n - 1; i >= 0; i--) {
// To store previous values
let backUp = 0;
for (let j = i; j < n; j++) {
if (j === i)
L[j] = 1;
else if (S.charAt(i) === S.charAt(j)) {
const temp = L[j];
L[j] = backUp + 2;
backUp = temp;
} else {
backUp = L[j];
L[j] = Math.max(L[j], L[j - 1]);
}
}
}
// Return final answer
return L[n - 1];
}
static minimumNumberOfDeletions(S) {
const n = S.length;
// Find the longest palindromic subsequence
const len = Solution.lps(S);
// After removing characters other than the lps, we get a palindrome.
return n - len;
}
} // Example usage const inputString = "examplestring" ;
const result = Solution.minimumNumberOfDeletions(inputString); console.log( "Minimum number of deletions: " + result);
|
Time Complexity: O(n^2), where n is the length of the input string.
Auxiliary Space: O(n) as a 1D array of size n is used to store the subproblems.