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
Table of Content
[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.
#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;
}
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));
}
}
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))
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));
}
}
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 allowedkchanges.
#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;
}
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));
}
}
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))
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));
}
}
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)