Open In App

Convert s1 into a Palindrome such that s1 contains s2 as Substring

Last Updated : 02 May, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given two strings s1 and s2, The task is to convert s1 into a palindrome such that s1 contains s2 as a substring in a minimum number of operations. In a single operation, we can replace any word of s1 with any character. If it is not possible to convert s1 such that it is a palindrome as well as contains a substring of s2, then return -1.

Examples:

Input: s1 = “abaa”,  s2 = “bb”
Output: 1
Explanation: We can replace s1[2]=’a’ with ‘b’. So, the new s1 will be like “abba”, having s2 as a substring.

Input: s1 = “abbd”,  s2 = “mr”
Output: 4
Explanation:

  • 1st: s1=”mrbd”, 2 operations (this is the minimum operation to make s2 a substring of s1) 
  • 2nd: s1=”mrrm”,  2 operations  (this is the minimum operation to make s1 palindrome)

Approach: To solve the problem follow the below idea:

The idea is for each index i in s1 we will include s2 and check if it is possible to convert the new string to palindrome without changing the included string s2. If it is possible calculate the cost for each index and return the minimum one, if not then return -1.

Steps to solve the above approach:

  • Traverse string s1 from [0, l1-l2] both inclusive and for each index, i create a new string temp.
  • Temp = k1(substring of s1 from [0, i] ) + s2 + k2(substring of s2 from i+l2 till l1 i.e. [i + l2, l1] ) 
    • For every such replacement of s2 in s1 keep on storing the cost.
    • Now for every such temp created, we need to check if it is possible to create the palindrome without changing replaced s2
    • Run a loop in for every j in temp from [0, ceil(l1/2)) as we are checking for palindrome so no need to traverse half string 
    • If pointer j is outside the indexes of s2 i.e. j < i || j ≥ i + l2 and temp[j]!=temp[l1-j-1] update cost++
    • Now if pointer j is inside the indexes of s2 then we will check if pointer l1-j-1 is outside of indexes of s2 i.e. l1-j-1<i or l1 – j – 1 ≥ i + l2 and temp[j]!=temp[l1-j-1] update cost++.
    • Else if both pointer j and l1-j-1 are inside the indexes of s2 and temp[j]!=temp[l1-j-1] then break the loop. For this index i the cost will be -1.
  • Return the minimum cost for the whole string, return -1 if not possible.

Below is the code to implement the above approach:

C++




// C++ code for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to count number of operations
// required
int specialPalindrome(string s1, string s2)
{
    int l1 = s1.length(), l2 = s2.length();
    int ans = INT_MAX;
    for (int i = 0; i < l1 - l2 + 1; i++) {
 
        // Place s2 in all possible
        // positions in s1
        string temp
            = s1.substr(0, i) + s2 + s1.substr(i + l2);
        int cost = 0;
 
        // Calculate cost to place s2
        for (int j = i; j < i + l2; j++) {
 
            if (s1[j] != temp[j])
                cost++;
        }
        int z = 0;
 
        // Find the cost to convert new
        // string to palindrome
        for (int j = 0; j < ceil(l1 / 2.0); j++) {
 
            // If s2 is in the
            // first half of new
            // string
            if ((j < i || j >= i + l2)
                && temp[j] != temp[l1 - j - 1])
                cost++;
 
            // If s2 is in the second
            // half of new string
            else if (temp[j] != temp[l1 - j - 1]
                     && (l1 - j - 1 < i
                         || l1 - j - 1 >= i + l2))
                cost++;
 
            // If s2 is in both halves
            else if (temp[j] != temp[l1 - j - 1]) {
 
                z = 1;
                break;
            }
        }
        if (z == 0)
            ans = min(ans, cost);
    }
    if (ans == INT_MAX) {
        return -1;
    }
    return ans;
}
 
// Driver code
int main()
{
 
    string s1 = "abaa", s2 = "bb";
 
    // Function call
    int ans = specialPalindrome(s1, s2);
    cout << ans;
    return 0;
}


Java




// Java code for the above approach
import java.util.*;
 
public class Main {
 
    // Function to count number of operations
    // required
    public static int specialPalindrome(String s1,
                                        String s2)
    {
        int l1 = s1.length(), l2 = s2.length();
        int ans = Integer.MAX_VALUE;
        for (int i = 0; i < l1 - l2 + 1; i++) {
 
            // Place s2 in all possible
            // positions in s1
            String temp = s1.substring(0, i) + s2
                          + s1.substring(i + l2);
            int cost = 0;
 
            // Calculate cost to place s2
            for (int j = i; j < i + l2; j++) {
 
                if (s1.charAt(j) != temp.charAt(j))
                    cost++;
            }
            int z = 0;
 
            // Find the cost to convert new
            // string to palindrome
            for (int j = 0; j < Math.ceil(l1 / 2.0); j++) {
 
                // If s2 is in the
                // first half of new
                // string
                if ((j < i || j >= i + l2)
                    && temp.charAt(j)
                           != temp.charAt(l1 - j - 1))
                    cost++;
 
                // If s2 is in the second
                // half of new string
                else if (temp.charAt(j)
                             != temp.charAt(l1 - j - 1)
                         && (l1 - j - 1 < i
                             || l1 - j - 1 >= i + l2))
                    cost++;
 
                // If s2 is in both halves
                else if (temp.charAt(j)
                         != temp.charAt(l1 - j - 1)) {
 
                    z = 1;
                    break;
                }
            }
            if (z == 0)
                ans = Math.min(ans, cost);
        }
        if (ans == Integer.MAX_VALUE) {
            return -1;
        }
        return ans;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        String s1 = "abaa", s2 = "bb";
 
        // Function call
        int ans = specialPalindrome(s1, s2);
        System.out.println(ans);
    }
}
// This code is contributed by Prajwal Kandekar


Python3




# Python3 code for the above approach
 
import math
 
# Function to count number of operations required
def specialPalindrome(s1, s2):
 
    l1 = len(s1)
    l2 = len(s2)
    ans = float('inf')
 
    for i in range(l1-l2+1):
 
        # Place s2 in all possible positions in s1
        temp = s1[:i] + s2 + s1[i+l2:]
 
        cost = 0
        # Calculate cost to place s2
        for j in range(i, i+l2):
            if s1[j] != temp[j]:
                cost += 1
 
        z = 0
        # Find the cost to convert new string to palindrome
        for j in range(math.ceil(l1/2)):
            # If s2 is in the first half of new string
            if (j < i or j >= i+l2) and temp[j] != temp[l1-j-1]:
                cost += 1
            # If s2 is in the second half of new string
            elif temp[j] != temp[l1-j-1] and (l1-j-1 < i or l1-j-1 >= i+l2):
                cost += 1
            # If s2 is in both halves
            elif temp[j] != temp[l1-j-1]:
                z = 1
                break
 
        if z == 0:
            ans = min(ans, cost)
 
    if ans == float('inf'):
        return -1
    return ans
 
# Driver code
if __name__ == '__main__':
    s1 = "abaa"
    s2 = "bb"
 
    # Function call
    ans = specialPalindrome(s1, s2)
    print(ans)


C#




// C# code for the above approach
 
using System;
 
public class GFG {
 
    // Function to count number of operations required
    static int specialPalindrome(string s1, string s2)
    {
 
        int l1 = s1.Length, l2 = s2.Length;
        int ans = int.MaxValue;
        for (int i = 0; i < l1 - l2 + 1; i++) {
 
            // Place s2 in all possible positions in s1
            string temp = s1.Substring(0, i) + s2
                          + s1.Substring(i + l2);
            int cost = 0;
 
            // Calculate cost to place s2
            for (int j = i; j < i + l2; j++) {
 
                if (s1[j] != temp[j])
                    cost++;
            }
            int z = 0;
 
            // Find the cost to convert new string to
            // palindrome
            for (int j = 0; j < Math.Ceiling(l1 / 2.0);
                 j++) {
 
                // If s2 is in the first half of new string
                if ((j < i || j >= i + l2)
                    && temp[j] != temp[l1 - j - 1])
                    cost++;
 
                // If s2 is in the second half of new string
                else if (temp[j] != temp[l1 - j - 1]
                         && (l1 - j - 1 < i
                             || l1 - j - 1 >= i + l2))
                    cost++;
 
                // If s2 is in both halves
                else if (temp[j] != temp[l1 - j - 1]) {
                    z = 1;
                    break;
                }
            }
            if (z == 0)
                ans = Math.Min(ans, cost);
        }
        if (ans == int.MaxValue) {
            return -1;
        }
        return ans;
    }
 
    static public void Main()
    {
 
        // Code
        string s1 = "abaa", s2 = "bb";
 
        // Function call
        int ans = specialPalindrome(s1, s2);
        Console.WriteLine(ans);
    }
}
 
// This code is contributed by karthik.


Javascript




// Javascript code for the above approach
 
function specialPalindrome(s1, s2) {
 
    let l1 = s1.length;
    let l2 = s2.length;
    let ans = Number.MAX_VALUE;
 
    for (let i = 0; i <= l1 - l2; i++) {
 
        // Place s2 in all possible positions in s1
        let temp = s1.substring(0, i) + s2 + s1.substring(i + l2);
 
        let cost = 0;
        // Calculate cost to place s2
        for (let j = i; j < i + l2; j++) {
            if (s1[j] != temp[j]) {
                cost += 1;
            }
        }
 
        let z = 0;
        // Find the cost to convert new string to palindrome
        for (let j = 0; j < Math.ceil(l1 / 2); j++) {
            // If s2 is in the first half of new string
            if ((j < i || j >= i + l2) && temp[j] != temp[l1 - j - 1]) {
                cost += 1;
            }
            // If s2 is in the second half of new string
            else if (temp[j] != temp[l1 - j - 1] && (l1 - j - 1 < i || l1 - j - 1 >= i + l2)) {
                cost += 1;
            }
            // If s2 is in both halves
            else if (temp[j] != temp[l1 - j - 1]) {
                z = 1;
                break;
            }
        }
 
        if (z == 0) {
            ans = Math.min(ans, cost);
        }
    }
 
    if (ans == Number.MAX_VALUE) {
        return -1;
    }
    return ans;
}
 
// Driver code
let s1 = "abaa";
let s2 = "bb";
 
// Function call
let ans = specialPalindrome(s1, s2);
console.log(ans);
 
// This code is contributed by Tapesh(tapeshuda420)


Output

1

Time Complexity: O(N*M) where N is size of s1 and M is size of s2
Auxiliary Space: O(N) because the maximum elements at a time in the temp are the size of S1.



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads