Open In App

Minimize adjacent character differences in palindromic string with ‘?’

Last Updated : 01 Aug, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given a string S. The string can contain small case English letters or ‘?’. You can replace ‘?’ with any small English letter. Now if it is possible to make the string S a palindrome after replacing all ‘?’ then find the palindromic string with a minimum sum of differences of adjacent characters. Otherwise, return -1.

Input: S = a???c??c????
Output: 4
Explanation: We can see that we can make the string palindrome. Now to get minimum sum we should replace all the ‘?’ between ‘a’ and ‘c’ with ‘b’ and all the ‘?’ between two ‘c’ with ‘c’. So after replacing all the ‘?’ the string:  abbbccccbbba. The sum of differences of adjacent characters is 4.

Input: S = a???c??c???c
Output: -1
Explanation: It is not possible to make the string palindrome.

Approach: To solve the  problem follow the below idea:

The idea is to iterate over the string from both ends, replace any ‘?’ character with the corresponding character from the other end if it is non ? character, and return -1 if it is not possible to make the string a palindrome. Calculate the minimum sum of differences of adjacent characters by iterating over the remaining characters in the first half of the string and multiplying the result by 2.

Below are the steps for the above approach:

  • Initialize the variables i, j, n, len_s, diff, and ans = 0.
  • Store the length of the input string s to len_s.
  • Iterate over the string s from both ends simultaneously using the variables i = 0 and j = len_s – 1.
  • If the characters at current positions match, continue to the next iteration, if (s[i] == s[j]), continue.
  • Check if (s[i] == ‘?’ && s[j] != ‘?’), replace s[i] with s[j], s[i] = s[j] and vice versa.
  • If neither character is ‘?’, return -1.
  • Calculate the number of characters to consider in the first half of the string s using the variable n.
    • Check if the length of the string s is odd, increment n by 1.
  • Find the first non-‘?’ character in the first half of the string and set last to it.
  • Iterate over the remaining characters in the first half of the string and calculate the minimum sum of absolute differences between adjacent characters using the variable ans.
  • If a character is ‘?’, skip it.
  • Calculate the absolute difference between the current character and the previous non-‘?’ character and add it to ans.
  • Set last to the current character.
  • Multiply the minimum sum by 2.

Below is the code for the above approach:

C++




// C++ code for the above approach:
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
 
int minimumSum(string s)
{
    int i, j, n, len_s, diff, ans = 0;
    char last = '\0';
 
    len_s = s.length();
 
    // Iterate over the string s from both
    // ends simultaneously
    for (i = 0, j = len_s - 1; i < j; i++, j--) {
 
        // If characters at current
        // positions match, continue
        if (s[i] == s[j]) {
            continue;
        }
 
        // If one character is '?' and the
        // other isn't, replace the '?'
        // with the other character
        else if (s[i] == '?' && s[j] != '?') {
            s[i] = s[j];
        }
        else if (s[i] != '?' && s[j] == '?') {
            s[j] = s[i];
        }
 
        // If neither character is '?',
        // it's not possible to make the
        // string palindromic, so return -1
        else {
            return -1;
        }
    }
 
    // Calculate the number of
    // characters to consider
    n = len_s / 2;
    if (len_s % 2 == 1) {
        n++;
    }
 
    // Find the first non-'?' character in
    // the first half of the string
    for (i = 0; i < n; i++) {
        if (s[i] != '?') {
            last = s[i];
            break;
        }
    }
 
    // Iterate over the remaining characters
    // and calculate the minimum sum of
    // absolute differences between
    // adjacent characters
    for (i = i + 1; i < n; i++) {
        if (s[i] == '?') {
            continue;
        }
        diff = abs(s[i] - last);
        ans += diff;
        last = s[i];
    }
 
    // Multiply the minimum sum by
    // 2 and return it
    return 2 * ans;
}
 
// Drivers code
int main()
{
    string s = "a???c??c????";
 
    // Function call
    cout << minimumSum(s) << endl;
    return 0;
}


Java




import java.lang.Math;
 
public class Main {
    public static int minimumSum(String s)
    {
        int i, j, n, len_s, diff, ans = 0;
        char last = '\0';
 
        len_s = s.length();
 
        // Iterate over the string s from both ends
        // simultaneously
        for (i = 0, j = len_s - 1; i < j; i++, j--) {
            // If characters at current positions match,
            // continue
            if (s.charAt(i) == s.charAt(j)) {
                continue;
            }
            // If one character is '?' and the other isn't,
            // replace the '?' with the other character
            else if (s.charAt(i) == '?'
                     && s.charAt(j) != '?') {
                s = s.substring(0, i) + s.charAt(j)
                    + s.substring(i + 1);
            }
            else if (s.charAt(i) != '?'
                     && s.charAt(j) == '?') {
                s = s.substring(0, j) + s.charAt(i)
                    + s.substring(j + 1);
            }
            // If neither character is '?', it's not
            // possible to make the string palindromic, so
            // return -1
            else {
                return -1;
            }
        }
 
        // Calculate the number of characters to consider
        n = len_s / 2;
        if (len_s % 2 == 1) {
            n++;
        }
 
        // Find the first non-'?' character in the first
        // half of the string
        for (i = 0; i < n; i++) {
            if (s.charAt(i) != '?') {
                last = s.charAt(i);
                break;
            }
        }
 
        // Iterate over the remaining characters and
        // calculate the minimum sum of absolute differences
        // between adjacent characters
        for (i = i + 1; i < n; i++) {
            if (s.charAt(i) == '?') {
                continue;
            }
            diff = Math.abs(s.charAt(i) - last);
            ans += diff;
            last = s.charAt(i);
        }
 
        // Multiply the minimum sum by 2 and return it
        return 2 * ans;
    }
 
    public static void main(String[] args)
    {
        String s = "a???c??c????";
        System.out.println(minimumSum(s));
    }
}


Python3




def minimumSum(s):
    # Initialize variables
    i, j, n, len_s, diff, ans = 0, 0, 0, len(s), 0, 0
    last = ''
 
    # Iterate over the string s from both ends simultaneously
    for i, j in zip(range(len_s//2), range(len_s-1, len_s//2-1, -1)):
        # If characters at current positions match, continue
        if s[i] == s[j]:
            continue
        # If one character is '?' and the other isn't, replace the '?' with the other character
        elif s[i] == '?' and s[j] != '?':
            s = s[:i] + s[j] + s[i + 1:]
        elif s[i] != '?' and s[j] == '?':
            s = s[:j] + s[i] + s[j + 1:]
        # If neither character is '?', it's not possible to make the string palindromic, so return -1
        else:
            return -1
 
    # Calculate the number of characters to consider
    n = len_s // 2 if len_s % 2 == 0 else len_s // 2 + 1
 
    # Find the first non-'?' character in the first half of the string
    for i in range(n):
        if s[i] != '?':
            last = s[i]
            break
 
    # Iterate over the remaining characters and calculate the minimum sum of absolute differences between adjacent characters
    for i in range(i + 1, n):
        if s[i] == '?':
            continue
        diff = abs(ord(s[i]) - ord(last))
        ans += diff
        last = s[i]
 
    # Multiply the minimum sum by 2 and return it
    return 2 * ans
 
 
if __name__ == "__main__":
    s = "a???c??c????"
    result = minimumSum(s)
    print(result)


C#




// C++ code for the above approach:
using System;
 
public class Program
{
    public static int MinimumSum(string s)
    {
        int n, len_s, diff, ans = 0;
        char last = '\0';
 
        len_s = s.Length;
 
        // Iterate over the string s from both ends simultaneously
        for (int i = 0, j = len_s - 1; i < j; i++, j--)
        {
            // If characters at current positions match, continue
            if (s[i] == s[j])
            {
                continue;
            }
 
            // If one character is '?' and the other isn't, replace the '?' with the other character
            else if (s[i] == '?' && s[j] != '?')
            {
                s = s.Substring(0, i) + s[j] + s.Substring(i + 1);
            }
            else if (s[i] != '?' && s[j] == '?')
            {
                s = s.Substring(0, j) + s[i] + s.Substring(j + 1);
            }
 
            // If neither character is '?', it's not possible to make the string palindromic, so return -1
            else
            {
                return -1;
            }
        }
 
        // Calculate the number of characters to consider
        n = len_s / 2;
        if (len_s % 2 == 1)
        {
            n++;
        }
 
        // Find the first non-'?' character in the first half of the string
        for (int i = 0; i < n; i++)
        {
            if (s[i] != '?')
            {
                last = s[i];
                break;
            }
        }
 
        // Iterate over the remaining characters and calculate the minimum sum of absolute differences between adjacent characters
        for (int i = n; i < len_s; i++)
        {
            if (s[i] == '?')
            {
                continue;
            }
            diff = Math.Abs(s[i] - last);
            ans += diff;
            last = s[i];
        }
 
        // Multiply the minimum sum by 2 and return it
        return ans;
    }
 
    public static void Main(string[] args)
    {
        string s = "a???c??c????";
 
        // Function call
        Console.WriteLine(MinimumSum(s));
    }
}
// This code was contributed by codearcade


Javascript




// JavaScript code for the above approach:
function minimumSum(s) {
     
    // Initialize variables
    let i = 0, j = 0, n = 0, len_s = s.length, diff = 0, ans = 0;
    let last = '';
 
    // Iterate over the string s from both
    // ends simultaneously
    for (i = 0, j = len_s - 1; i < j; i++, j--) {
         
        // If characters at current
        // positions match, continue
        if (s[i] == s[j]) {
            continue;
        }
        // If one character is '?' and the
        // other isn't, replace the '?'
        // with the other character
        else if (s[i] == '?' && s[j] != '?') {
            s = s.substring(0, i) + s[j] + s.substring(i + 1);
        }
        else if (s[i] != '?' && s[j] == '?') {
            s = s.substring(0, j) + s[i] + s.substring(j + 1);
        }
        // If neither character is '?',
        // it's not possible to make the
        // string palindromic, so return -1
        else {
            return -1;
        }
    }
 
    // Calculate the number of
    // characters to consider
    n = len_s % 2 == 0 ? len_s / 2 : Math.floor(len_s / 2) + 1;
 
    // Find the first non-'?' character in
    // the first half of the string
    for (i = 0; i < n; i++) {
        if (s[i] != '?') {
            last = s[i];
            break;
        }
    }
 
    // Iterate over the remaining characters
    // and calculate the minimum sum of
    // absolute differences between
    // adjacent characters
    for (i = i + 1; i < n; i++) {
        if (s[i] == '?') {
            continue;
        }
        diff = Math.abs(s[i].charCodeAt(0) - last.charCodeAt(0));
        ans += diff;
        last = s[i];
    }
 
    // Multiply the minimum sum by
    // 2 and return it
    return 2 * ans;
}
 
// Driver code
let s = "a???c??c????";
console.log(minimumSum(s));
 
// This code is contributed by prasad264


Output

4

Time Complexity: O(N), N is the length of the input string S
Auxiliary Space: O(1)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads