Open In App

Make largest palindrome by changing at most K-digits

Last Updated : 11 May, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

You are given a string s consisting of digits (0-9) and an integer k. Convert the string into a palindrome by changing at most k digits. If multiple palindromes are possible, return the lexicographically largest one. If it's impossible to form a palindrome with k changes, return "Not Possible".

Examples: 

Input: s = “19495”, k = 3
Output: "99999"
Explanation: Lexicographically largest palindrome after 3 changes is "99999"

Input: s = “43436”, k = 1
Output: “63436”
Explanation: Lexicographically largest palindrome after 1 change is “63436”

Input: s = “11345”, k = 1
Output: "Not Possible"
Explanation: It is not possible to make s palindrome after 1 changes

[Approach 1] Using Two Pointers - O(n) time and O(n) space

  • Solve this problem using two pointers method. We start from left and right and if both digits are not equal then we replace the smaller value with larger value and decrease k by 1.
  • Stop when the left and right pointers cross each other, after they stop if value of k is negative, then it is not possible to make string palindrome using k changes. If k is positive, then we can further maximize the string by looping once again in the same manner from left and right and converting both the digits to 9 and decreasing k by 2.
  • If k value remains to 1 and string length is odd then we make the middle character as 9 to maximize whole value.
C++
#include <iostream>
using namespace std;

string maxPalindrome(string s, int k)
{
    string palin = s;

    // Initialize l and r by leftmost and
    // rightmost ends
    int l = 0;
    int r = s.length() - 1;

    //  first try to make string palindrome
    while (l < r)
    {

        // Replace left and right character by
        // maximum of both
        if (s[l] != s[r])
        {
            palin[l] = palin[r] = max(s[l], s[r]);
            k--;
        }
        l++;
        r--;
    }

    // If k is negative then we can't make
    // string palindrome
    if (k < 0)
        return "Not possible";

    l = 0;
    r = s.length() - 1;

    while (l <= r)
    {

        // At mid character, if K>0 then change
        // it to 9
        if (l == r)
        {
            if (k > 0)
                palin[l] = '9';
        }

        // If character at lth (same as rth) is
        // less than 9
        if (palin[l] < '9')
        {
            /* If none of them is changed in the
               previous loop then subtract 2 from K
               and convert both to 9 */
            if (k >= 2 && palin[l] == s[l] && palin[r] == s[r])
            {
                k -= 2;
                palin[l] = palin[r] = '9';
            }

            /*  If one of them is changed
                in the previous
                loop then subtract 1 from K
                (1 more is
                subtracted already) and make them 9  */
            else if (k >= 1 && (palin[l] != s[l] || palin[r] != s[r]))
            {
                k--;
                palin[l] = palin[r] = '9';
            }
        }
        l++;
        r--;
    }

    return palin;
}

int main()
{
    string s = "19495";
    int k = 3;
    cout << maxPalindrome(s, k);
    return 0;
}
Java
import java.util.*;

public class GfG {
    public static String maxPalindrome(String s, int k)
    {
        StringBuilder palin = new StringBuilder(s);

        // Initialize l and r by leftmost and
        // rightmost ends
        int l = 0;
        int r = s.length() - 1;

        // first try to make string palindrome
        while (l < r) {
            // Replace left and right character by
            // maximum of both
            if (s.charAt(l) != s.charAt(r)) {
                palin.setCharAt(
                    l, (char)Math.max(s.charAt(l),
                                      s.charAt(r)));
                palin.setCharAt(
                    r, (char)Math.max(s.charAt(l),
                                      s.charAt(r)));
                k--;
            }
            l++;
            r--;
        }

        // If k is negative then we can't make
        // string palindrome
        if (k < 0)
            return "Not possible";

        l = 0;
        r = s.length() - 1;

        while (l <= r) {
            // At mid character, if K>0 then change
            // it to 9
            if (l == r) {
                if (k > 0)
                    palin.setCharAt(l, '9');
            }

            // If character at lth (same as rth) is
            // less than 9
            if (palin.charAt(l) < '9') {
                /* If none of them is changed in the
                   previous loop then subtract 2 from K
                   and convert both to 9 */
                if (k >= 2 && palin.charAt(l) == s.charAt(l)
                    && palin.charAt(r) == s.charAt(r)) {
                    k -= 2;
                    palin.setCharAt(l, '9');
                    palin.setCharAt(r, '9');
                }

                /*  If one of them is changed
                    in the previous
                    loop then subtract 1 from K
                    (1 more is
                    subtracted already) and make them 9  */
                else if (k >= 1
                         && (palin.charAt(l) != s.charAt(l)
                             || palin.charAt(r)
                                    != s.charAt(r))) {
                    k--;
                    palin.setCharAt(l, '9');
                    palin.setCharAt(r, '9');
                }
            }
            l++;
            r--;
        }

        return palin.toString();
    }

    public static void main(String[] args)
    {
        String s = "19495";
        int k = 3;
        System.out.println(maxPalindrome(s, k));
    }
}
Python
def max_palindrome(s, k):
    palin = list(s)

    # Initialize l and r by leftmost and rightmost ends
    l = 0
    r = len(s) - 1

    # first try to make string palindrome
    while l < r:
        # Replace left and right character by maximum of both
        if s[l] != s[r]:
            palin[l] = palin[r] = max(s[l], s[r])
            k -= 1
        l += 1
        r -= 1

    # If k is negative then we can't make string palindrome
    if k < 0:
        return "Not possible"

    l = 0
    r = len(s) - 1

    while l <= r:
        # At mid character, if K>0 then change it to 9
        if l == r:
            if k > 0:
                palin[l] = '9'

        # If character at lth (same as rth) is less than 9
        if palin[l] < '9':
            # If none of them is changed in the previous loop then subtract 2 from K and convert both to 9
            if k >= 2 and palin[l] == s[l] and palin[r] == s[r]:
                k -= 2
                palin[l] = palin[r] = '9'
            # If one of them is changed in the previous loop then subtract 1 from K (1 more is subtracted already) and make them 9
            elif k >= 1 and (palin[l] != s[l] or palin[r] != s[r]):
                k -= 1
                palin[l] = palin[r] = '9'
        l += 1
        r -= 1

    return ''.join(palin)


s = "19495"
k = 3
print(max_palindrome(s, k))
C#
using System;

class GfG {
    public static string MaxPalindrome(string s, int k)
    {
        char[] palin = s.ToCharArray();

        // Initialize l and r by leftmost and
        // rightmost ends
        int l = 0;
        int r = s.Length - 1;

        // first try to make string palindrome
        while (l < r) {
            // Replace left and right character by
            // maximum of both
            if (s[l] != s[r]) {
                palin[l] = (char)Math.Max(s[l], s[r]);
                palin[r] = (char)Math.Max(s[l], s[r]);
                k--;
            }
            l++;
            r--;
        }

        // If k is negative then we can't make
        // string palindrome
        if (k < 0)
            return "Not possible";

        l = 0;
        r = s.Length - 1;

        while (l <= r) {
            // At mid character, if K>0 then change
            // it to 9
            if (l == r) {
                if (k > 0)
                    palin[l] = '9';
            }

            // If character at lth (same as rth) is
            // less than 9
            if (palin[l] < '9') {
                /* If none of them is changed in the
                   previous loop then subtract 2 from K
                   and convert both to 9 */
                if (k >= 2 && palin[l] == s[l]
                    && palin[r] == s[r]) {
                    k -= 2;
                    palin[l] = '9';
                    palin[r] = '9';
                }

                /*  If one of them is changed
                    in the previous
                    loop then subtract 1 from K
                    (1 more is
                    subtracted already) and make them 9  */
                else if (k >= 1
                         && (palin[l] != s[l]
                             || palin[r] != s[r])) {
                    k--;
                    palin[l] = '9';
                    palin[r] = '9';
                }
            }
            l++;
            r--;
        }

        return new string(palin);
    }

    static void Main()
    {
        string s = "19495";
        int k = 3;
        Console.WriteLine(MaxPalindrome(s, k));
    }
}
JavaScript
function maxPalindrome(s, k)
{
    let palin = s.split("");

    // Initialize l and r by leftmost and rightmost ends
    let l = 0;
    let r = s.length - 1;

    // first try to make string palindrome
    while (l < r) {
        // Replace left and right character by maximum of
        // both
        if (s[l] !== s[r]) {
            palin[l] = palin[r] = Math.max(s[l], s[r]);
            k--;
        }
        l++;
        r--;
    }

    // If k is negative then we can't make string palindrome
    if (k < 0)
        return "Not possible";

    l = 0;
    r = s.length - 1;

    while (l <= r) {
        // At mid character, if K>0 then change it to 9
        if (l === r) {
            if (k > 0)
                palin[l] = "9";
        }

        // If character at lth (same as rth) is less than 9
        if (palin[l] < "9") {
            // If none of them is changed in the previous
            // loop then subtract 2 from K and convert both
            // to 9
            if (k >= 2 && palin[l] === s[l]
                && palin[r] === s[r]) {
                k -= 2;
                palin[l] = palin[r] = "9";
            }
            // If one of them is changed in the previous
            // loop then subtract 1 from K (1 more is
            // subtracted already) and make them 9
            else if (k >= 1
                     && (palin[l] !== s[l]
                         || palin[r] !== s[r])) {
                k--;
                palin[l] = palin[r] = "9";
            }
        }
        l++;
        r--;
    }

    return palin.join("");
}

const s = "19495";
const k = 3;
console.log(maxPalindrome(s, k));

Output
99999

Time complexity: O(n)
Auxiliary Space: O(n)

[Approach 2] Using Greedy Algorithm - O(n) time and O(1) space

In this approach, we greedily first count the required changes to make the string a palindrome by comparing characters from both ends. If the changes exceed k, return "Not Possible". Then, we traverse the string again to maximize it lexicographically by changing characters to '9' where possible, without exceeding the allowed k changes.

C++
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;

string maxPalindrome(string s, int k)
{
    int n = s.length();
    int replacements = 0;

    // First pass: Make the string a palindrome
    // by counting required replacements
    for (int i = 0, j = n - 1; i < j; i++, j--)
    {
        if (s[i] != s[j])
        {
            replacements++;
            if (replacements > k)
                return "Not Possible";
        }
    }

    // Second pass: Maximize the palindrome lexicographically
    for (int i = 0, j = n - 1; i <= j && k > 0; i++, j--)
    {
        // Middle element for odd-length strings
        if (i == j)
        {
            s[i] = '9';
        }
        else if (s[i] != s[j])
        {
            // Can afford one more change
            if ((k - replacements >= 1) && (max(s[i], s[j]) != '9'))
            {
                // Maximize both characters
                s[i] = s[j] = '9';
                replacements--;
                k -= 2;
            }
            else
            {
                s[i] = s[j] = max(s[i], s[j]);
                replacements--;
                k -= 1;
            }
        }

        // If already equal, maximize
        else if (k - replacements >= 2 && s[i] != '9')
        {
            s[i] = s[j] = '9';
            k -= 2;
        }
    }

    return s;
}

int main()
{
    string s = "19495";
    int k = 3;
    cout << maxPalindrome(s, k);
    return 0;
}
Java
import java.util.*;

public class GfG{
    public static String maxPalindrome(String s, int k) {
        int n = s.length();
        int replacements = 0;

        // First pass: Make the string a palindrome
        // by counting required replacements
        for (int i = 0, j = n - 1; i < j; i++, j--) {
            if (s.charAt(i) != s.charAt(j)) {
                replacements++;
                if (replacements > k)
                    return "Not Possible";
            }
        }

        // Second pass: Maximize the palindrome lexicographically
        for (int i = 0, j = n - 1; i <= j && k > 0; i++, j--) {
            
            // Middle element for odd-length strings
            if (i == j) {
                s = s.substring(0, i) + '9' + s.substring(i + 1);
            } else if (s.charAt(i) != s.charAt(j)) {
                
                // Can afford one more change
                if ((k - replacements >= 1) && (Math.max(s.charAt(i), s.charAt(j)) != '9')) {
                   
                    // Maximize both characters
                    s = s.substring(0, i) + '9' + '9' + s.substring(j + 1);
                    replacements--;
                    k -= 2;
                } else {
                    s = s.substring(0, i) + Math.max(s.charAt(i), s.charAt(j)) + s.substring(i + 1);
                    replacements--;
                    k -= 1;
                }
            } else if (k - replacements >= 2 && s.charAt(i) != '9') {
                s = s.substring(0, i) + '9' + '9' + s.substring(j + 1);
                k -= 2;
            }
        }

        return s;
    }

    public static void main(String[] args) {
        String s = "19495";
        int k = 3;
        System.out.println(maxPalindrome(s, k));
    }
}
Python
def maxPalindrome(s, k):
    n = len(s)
    replacements = 0

    # First pass: Make the string a palindrome
    # by counting required replacements
    for i in range(n // 2):
        j = n - 1 - i
        if s[i] != s[j]:
            replacements += 1
            if replacements > k:
                return "Not Possible"

    # Second pass: Maximize the palindrome lexicographically
    s = list(s)
    for i in range((n + 1) // 2):
        j = n - 1 - i
        
        # Middle element for odd-length strings
        if i == j:
            s[i] = '9'
        elif s[i] != s[j]:

            # Can afford one more change
            if (k - replacements >= 1) and (max(s[i], s[j]) != '9'):

                # Maximize both characters
                s[i] = s[j] = '9'
                replacements -= 1
                k -= 2
            else:
                s[i] = s[j] = max(s[i], s[j])
                replacements -= 1
                k -= 1

        # If already equal, maximize
        elif k - replacements >= 2 and s[i] != '9':
            s[i] = s[j] = '9'
            k -= 2
    return ''.join(s)


# Example usage
s = "19495"
k = 3
print(maxPalindrome(s, k))
C#
using System;

class GfG{
    public static string MaxPalindrome(string s, int k) {
        int n = s.Length;
        int replacements = 0;

        // First pass: Make the string a palindrome
        // by counting required replacements
        for (int i = 0, j = n - 1; i < j; i++, j--) {
            if (s[i] != s[j]) {
                replacements++;
                if (replacements > k)
                    return "Not Possible";
            }
        }

        // Second pass: Maximize the palindrome lexicographically
        char[] arr = s.ToCharArray();
        for (int i = 0, j = n - 1; i <= j && k > 0; i++, j--) {
            
            // Middle element for odd-length strings
            if (i == j) {
                arr[i] = '9';
            } else if (arr[i] != arr[j]) {
                
                // Can afford one more change
                if ((k - replacements >= 1) && (Math.Max(arr[i], arr[j]) != '9')) {
                    
                    // Maximize both characters
                    arr[i] = arr[j] = '9';
                    replacements--;
                    k -= 2;
                } else {
                    arr[i] = arr[j] = Math.Max(arr[i], arr[j]);
                    replacements--;
                    k -= 1;
                }
            } else if (k - replacements >= 2 && arr[i] != '9') {
                arr[i] = arr[j] = '9';
                k -= 2;
            }
        }

        return new string(arr);
    }

    static void Main() {
        string s = "19495";
        int k = 3;
        Console.WriteLine(MaxPalindrome(s, k));
    }
}
JavaScript
function maxPalindrome(s, k)
{
    let n = s.length;
    let replacements = 0;

    // First pass: Make the string a palindrome
    // by counting required replacements
    for (let i = 0, j = n - 1; i < j; i++, j--) {
        if (s[i] !== s[j]) {
            replacements++;
            if (replacements > k)
                return "Not Possible";
        }
    }

    // Second pass: Maximize the palindrome
    // lexicographically
    s = s.split("");
    for (let i = 0, j = n - 1; i <= j && k > 0; i++, j--) {
        
        // Middle element for odd-length strings
        if (i === j) {
            s[i] = "9";
        }
        else if (s[i] !== s[j]) {
            
            // Can afford one more change
            if ((k - replacements >= 1)
                && (Math.max(s[i], s[j]) !== "9")) {
            
                // Maximize both characters
                s[i] = s[j] = "9";
                replacements--;
                k -= 2;
            }
            else {
                s[i] = s[j] = Math.max(s[i], s[j]);
                replacements--;
                k -= 1;
            }
        }
        else if (k - replacements >= 2 && s[i] !== "9") {
            s[i] = s[j] = "9";
            k -= 2;
        }
    }

    return s.join("");
}

let s = "19495";
let k = 3;
console.log(maxPalindrome(s, k));

Output
99999

Time complexity: O(n)
Auxiliary Space: O(1)


Next Article
Article Tags :

Similar Reads