Form the largest palindromic number using atmost two swaps

• Difficulty Level : Medium
• Last Updated : 09 Jul, 2021

Given a non-negative palindromic number num containing n number of digits. The problem is to apply at most two swap operations on the number num so that the resultant is the largest possible palindromic number.
Examples:

Input  : 4697557964
Output : 9647557469
In, 4697557964 the highlighted digits were
swapped to get the largest palindromic number
9647557469.

Input : 54345
Output : 54345
No swapping of digits required.

Approach: If n < 3, then num itself is the largest possible palindromic number. Else calculate mid = (n / 2) – 1. Then create an array rightMax[] of size (mid + 1). rightMax[i] contains the index of the greatest digit which is on the right side of num[i] and also greater than num[i] and 0 <= i <= mid. If no such digit exists then rightMax[i] = -1. Now, traverse the rightMax[] array from i = 0 to m, and find the first element having rightMax[i] != -1. Perform the swap(num[i], num[rightMax[i]]) and swap(num[n – i – 1], num[n – rightMax[i] – 1]) operations and break.

C++

 // C++ implementation to form the largest palindromic// number using atmost two swaps#include  using namespace std; // function to form the largest palindromic// number using atmost two swapsvoid largestPalin(char num[], int n){    // if length of number is less than '3'    // then no higher palindromic number    // can be formed    if (n <= 3)        return;     // find the index of last digit    // in the 1st half of 'num'    int mid = n / 2 - 1;     int rightMax[mid + 1], right;     // as only the first half of 'num[]' is    // being considered, therefore    // for the rightmost digit in the first half    // of 'num[]', there will be no greater right digit    rightMax[mid] = -1;     // index of the greatest right digit till the    // current index from the right direction    right = mid;     // traverse the array from second right element    // in the first half of 'num[]' up to the    // left element    for (int i = mid - 1; i >= 0; i--) {         // if 'num[i]' is less than the greatest digit        // encountered so far        if (num[i] < num[right])            rightMax[i] = right;         else {             // there is no greater right digit            // for 'num[i]'            rightMax[i] = -1;             // update 'right' index            right = i;        }    }     // traverse the 'rightMax[]' array from left to right    for (int i = 0; i <= mid; i++) {         // if for the current digit, greater right digit exists        // then swap it with its greater right digit and also        // perform the required swap operation in the right halft        // of 'num[]' to maintain palindromic property, then break        if (rightMax[i] != -1) {             // performing the required swap operations            swap(num[i], num[rightMax[i]]);            swap(num[n - i - 1], num[n - rightMax[i] - 1]);            break;        }    }} // Driver program to test aboveint main(){    char num[] = "4697557964";    int n = strlen(num);    largestPalin(num, n);     // required largest palindromic number    cout << "Largest Palindrome: "         << num;     return 0;}

Java

 // Java implementation to form the largest palindromic// number using atmost two swapsclass GFG{ // function to form the largest palindromic// number using atmost two swapsstatic void largestPalin(char num[], int n){    // if length of number is less than '3'    // then no higher palindromic number    // can be formed    if (n <= 3)        return;     // find the index of last digit    // in the 1st half of 'num'    int mid = n / 2 - 1;     int []rightMax = new int[mid + 1];int right;     // as only the first half of 'num[]' is    // being considered, therefore    // for the rightmost digit in the first half    // of 'num[]', there will be no greater right digit    rightMax[mid] = -1;     // index of the greatest right digit till the    // current index from the right direction    right = mid;     // traverse the array from second right element    // in the first half of 'num[]' up to the    // left element    for (int i = mid - 1; i >= 0; i--)    {         // if 'num[i]' is less than the greatest digit        // encountered so far        if (num[i] < num[right])            rightMax[i] = right;         else        {             // there is no greater right digit            // for 'num[i]'            rightMax[i] = -1;             // update 'right' index            right = i;        }    }     // traverse the 'rightMax[]' array from left to right    for (int i = 0; i <= mid; i++)    {         // if for the current digit, greater right digit exists        // then swap it with its greater right digit and also        // perform the required swap operation in the right halft        // of 'num[]' to maintain palindromic property, then break        if (rightMax[i] != -1)        {             // performing the required swap operations            swap(num,i, rightMax[i]);            swap(num,n - i - 1, n - rightMax[i] - 1);            break;        }    }} static char[] swap(char []arr, int i, int j){    char temp = arr[i];    arr[i] = arr[j];    arr[j] = temp;    return arr;} // Driver codepublic static void main(String[] args){    char num[] = "4697557964".toCharArray();    int n = num.length;    largestPalin(num, n);     // required largest palindromic number    System.out.println("Largest Palindrome: "        + String.valueOf(num));}} // This code has been contributed by 29AjayKumar

Python 3

 # Python implementation to form the largest# palindromic number using atmost two swaps # function to form the largest palindromic# number using atmost two swapsdef largestPalin(num, n):     # if length of number is less than '3'    # then no higher palindromic number    # can be formed    if n <= 3:        return     # find the index of last digit    # in the 1st half of 'num'    mid = n // 2 + 1     rightMax =  * (mid + 1)     # as only the first half of 'num[]' is    # being considered, therefore    # for the rightmost digit in the first half    # of 'num[]', there will be no greater right digit    rightMax[mid] = -1     # index of the greatest right digit till the    # current index from the right direction    right = mid     # traverse the array from second right element    # in the first half of 'num[]' up to the    # left element    for i in range(mid-1, -1, -1):                 # if 'num[i]' is less than the greatest digit        # encountered so far        if num[i] < num[right]:            rightMax[i] = right         else:             # there is no greater right digit            # for 'num[i]'            rightMax[i] = -1             # update 'right' index            right = i     # traverse the 'rightMax[]' array from left to right    for i in range(mid + 1):         # if for the current digit, greater right digit exists        # then swap it with its greater right digit and also        # perform the required swap operation in the right halft        # of 'num[]' to maintain palindromic property, then break        if rightMax[i] != -1:             # performing the required swap operations            num[i], num[rightMax[i]] = num[rightMax[i]], num[i]            num[n-i-1], num[n - rightMax[i] - 1] = num[n - rightMax[i] - 1], num[n - i - 1]            break  # Driver Codeif __name__ == "__main__":    num = "4697557964"    n = len(num)         # Required as string object do not    # support item assignment    num = list(num)    largestPalin(num, n)     # making string again from list    num = ''.join(num)    print("Largest Palindrome: ",num) # This code is contributed by# sanjeev2552

C#

 // C# implementation to form the largest// palindromic number using atmost two swapsusing System; class GFG{ // function to form the largest palindromic// number using atmost two swapsstatic void largestPalin(char []num, int n){    // if length of number is less than '3'    // then no higher palindromic number    // can be formed    if (n <= 3)        return;     // find the index of last digit    // in the 1st half of 'num'    int mid = n / 2 - 1;     int []rightMax = new int[mid + 1]; int right;     // as only the first half of 'num[]' is    // being considered, therefore    // for the rightmost digit in the first half    // of 'num[]', there will be no greater right digit    rightMax[mid] = -1;     // index of the greatest right digit till the    // current index from the right direction    right = mid;     // traverse the array from second right element    // in the first half of 'num[]' up to the    // left element    for (int i = mid - 1; i >= 0; i--)    {         // if 'num[i]' is less than the greatest        // digit encountered so far        if (num[i] < num[right])            rightMax[i] = right;         else        {             // there is no greater right digit            // for 'num[i]'            rightMax[i] = -1;             // update 'right' index            right = i;        }    }     // traverse the 'rightMax[]' array    // from left to right    for (int i = 0; i <= mid; i++)    {         // if for the current digit, greater right        // digit exists then swap it with its greater        // right digit and also perform the required        // swap operation in the right half of 'num[]'        // to maintain palindromic property, then break        if (rightMax[i] != -1)        {             // performing the required swap operations            swap(num, i, rightMax[i]);            swap(num, n - i - 1, n - rightMax[i] - 1);            break;        }    }} static char[] swap(char []arr, int i, int j){    char temp = arr[i];    arr[i] = arr[j];    arr[j] = temp;    return arr;} // Driver codepublic static void Main(String[] args){    char []num = "4697557964".ToCharArray();    int n = num.Length;    largestPalin(num, n);     // required largest palindromic number    Console.WriteLine("Largest Palindrome: " +                        String.Join("", num));}} // This code contributed by Rajput-Ji

Javascript



Output:

Largest Palindrome: 9647557469

Time Complexity: O(n).
Auxiliary Space: O(n).

My Personal Notes arrow_drop_up