Closest Palindrome

Last Updated : 16 Sep, 2026

Given a numeric string n, find the closest palindrome number such that the absolute difference between the palindrome and n is minimum. If there are multiple palindrome numbers with the same absolute difference, return the smaller one.

Examples: 

Input: n = "9"
Output: "9"
Explanation: 9 itself is a palindrome number.

Input: n = "489"
Output: "484"
Explanation: Closest palindrome numbers from 489 are 484 and 494. Since both have the same absolute difference, we return the smaller one, which is 484.

Input: n = "1234"
Output: "1221"
Explanation: Closest palindrome numbers from 1234 are 1221 and 1331. Since 1221 is closer than 1331, we return 1221.

Try It Yourself
redirect icon

[Naive Approach] Using Brute Force Approach

The idea is to check numbers just smaller than n and just greater than n until we find a palindrome on both sides. The first palindrome found on each side is the closest palindrome in that direction.

We then compare their differences with n and return the closer one. If both have the same difference, we return the smaller palindrome.

  • Start with smaller = n - 1 and larger = n + 1.
  • Move downward from smaller until a palindrome is found.
  • Move upward from larger until a palindrome is found.
  • Calculate the absolute difference of both palindromes from n.
  • Return the palindrome with the smaller difference.
  • If both differences are equal, return the smaller palindrome.
C++
#include <bits/stdc++.h>
using namespace std;

// Check whether a number is a palindrome
bool isPalindrome(string s)
{
    int i = 0, j = s.size() - 1;

    while (i < j)
    {
        if (s[i] != s[j])
            return false;

        i++;
        j--;
    }

    return true;
}

// Add 1 to a numeric string
string addOne(string s)
{
    int i = s.size() - 1;

    while (i >= 0 && s[i] == '9')
    {
        s[i] = '0';
        i--;
    }

    if (i < 0)
        return "1" + s;

    s[i]++;
    return s;
}

// Subtract 1 from a numeric string
string subtractOne(string s)
{
    int i = s.size() - 1;

    while (i >= 0 && s[i] == '0')
    {
        s[i] = '9';
        i--;
    }

    if (i >= 0)
        s[i]--;

    // Remove leading zeros
    int pos = 0;
    while (pos < s.size() - 1 && s[pos] == '0')
        pos++;

    return s.substr(pos);
}

// Compare two numeric strings
int compare(string a, string b)
{
    if (a.size() != b.size())
        return a.size() < b.size() ? -1 : 1;

    if (a == b)
        return 0;

    return a < b ? -1 : 1;
}

// Find absolute difference of two numeric strings
string difference(string a, string b)
{
    if (compare(a, b) < 0)
        swap(a, b);

    int i = a.size() - 1;
    int j = b.size() - 1;
    int borrow = 0;

    string res = "";

    while (i >= 0)
    {
        int x = (a[i] - '0') - borrow;
        int y = (j >= 0 ? b[j] - '0' : 0);

        if (x < y)
        {
            x += 10;
            borrow = 1;
        }
        else
        {
            borrow = 0;
        }

        res += char('0' + (x - y));

        i--;
        j--;
    }

    while (res.size() > 1 && res.back() == '0')
        res.pop_back();

    reverse(res.begin(), res.end());

    return res;
}

string closestPalindrome(string &n)
{
    // If n itself is a palindrome, return it
    if (isPalindrome(n))
        return n;

    string smaller = subtractOne(n);
    string larger = addOne(n);

    // Find the closest palindrome smaller than n
    while (!isPalindrome(smaller))
        smaller = subtractOne(smaller);

    // Find the closest palindrome greater than n
    while (!isPalindrome(larger))
        larger = addOne(larger);

    string diff1 = difference(n, smaller);
    string diff2 = difference(n, larger);

    // Choose the closer palindrome.
    // If the difference is equal, choose the smaller one.
    if (compare(diff1, diff2) <= 0)
        return smaller;

    return larger;
}

int main()
{
    string n = "9";
    cout << closestPalindrome(n) << endl;

    return 0;
}
Java
import java.util.*;

class GFG {

    // Check whether a number is a palindrome
    static boolean isPalindrome(String s)
    {
        int i = 0, j = s.length() - 1;

        while (i < j) {
            if (s.charAt(i) != s.charAt(j))
                return false;

            i++;
            j--;
        }

        return true;
    }

    // Add 1 to a numeric string
    static String addOne(String s)
    {
        StringBuilder sb = new StringBuilder(s);
        int i = sb.length() - 1;

        while (i >= 0 && sb.charAt(i) == '9') {
            sb.setCharAt(i, '0');
            i--;
        }

        if (i < 0)
            return "1" + sb.toString();

        sb.setCharAt(i, (char)(sb.charAt(i) + 1));
        return sb.toString();
    }

    // Subtract 1 from a numeric string
    static String subtractOne(String s)
    {
        StringBuilder sb = new StringBuilder(s);
        int i = sb.length() - 1;

        while (i >= 0 && sb.charAt(i) == '0') {
            sb.setCharAt(i, '9');
            i--;
        }

        if (i >= 0)
            sb.setCharAt(i, (char)(sb.charAt(i) - 1));

        // Remove leading zeros
        int pos = 0;
        while (pos < sb.length() - 1
               && sb.charAt(pos) == '0')
            pos++;

        return sb.substring(pos);
    }

    // Compare two numeric strings
    static int compare(String a, String b)
    {
        if (a.length() != b.length())
            return a.length() < b.length() ? -1 : 1;

        if (a.equals(b))
            return 0;

        return a.compareTo(b) < 0 ? -1 : 1;
    }

    // Find absolute difference of two numeric strings
    static String difference(String a, String b)
    {
        if (compare(a, b) < 0) {
            String temp = a;
            a = b;
            b = temp;
        }

        int i = a.length() - 1;
        int j = b.length() - 1;
        int borrow = 0;

        StringBuilder res = new StringBuilder();

        while (i >= 0) {
            int x = (a.charAt(i) - '0') - borrow;
            int y = (j >= 0 ? b.charAt(j) - '0' : 0);

            if (x < y) {
                x += 10;
                borrow = 1;
            }
            else {
                borrow = 0;
            }

            res.append((char)('0' + (x - y)));

            i--;
            j--;
        }

        while (res.length() > 1
               && res.charAt(res.length() - 1) == '0')
            res.deleteCharAt(res.length() - 1);

        return res.reverse().toString();
    }

    static String closestPalindrome(String n)
    {
        // If n itself is a palindrome, return it
        if (isPalindrome(n))
            return n;

        String smaller = subtractOne(n);
        String larger = addOne(n);

        // Find the closest palindrome smaller than n
        while (!isPalindrome(smaller))
            smaller = subtractOne(smaller);

        // Find the closest palindrome greater than n
        while (!isPalindrome(larger))
            larger = addOne(larger);

        String diff1 = difference(n, smaller);
        String diff2 = difference(n, larger);

        // Choose the closer palindrome.
        // If the difference is equal, choose the smaller
        // one.
        if (compare(diff1, diff2) <= 0)
            return smaller;

        return larger;
    }

    public static void main(String[] args)
    {
        String n = "9";
        System.out.println(closestPalindrome(n));
    }
}
Python
# Check whether a number is a palindrome
def isPalindrome(s):
    i = 0
    j = len(s) - 1

    while i < j:
        if s[i] != s[j]:
            return False

        i += 1
        j -= 1

    return True


# Add 1 to a numeric string
def addOne(s):
    s = list(s)
    i = len(s) - 1

    while i >= 0 and s[i] == '9':
        s[i] = '0'
        i -= 1

    if i < 0:
        return "1" + ''.join(s)

    s[i] = chr(ord(s[i]) + 1)
    return ''.join(s)


# Subtract 1 from a numeric string
def subtractOne(s):
    s = list(s)
    i = len(s) - 1

    while i >= 0 and s[i] == '0':
        s[i] = '9'
        i -= 1

    if i >= 0:
        s[i] = chr(ord(s[i]) - 1)

    # Remove leading zeros
    pos = 0
    while pos < len(s) - 1 and s[pos] == '0':
        pos += 1

    return ''.join(s[pos:])


# Compare two numeric strings
def compare(a, b):
    if len(a) != len(b):
        return -1 if len(a) < len(b) else 1

    if a == b:
        return 0

    return -1 if a < b else 1


# Find absolute difference of two numeric strings
def difference(a, b):
    if compare(a, b) < 0:
        a, b = b, a

    i = len(a) - 1
    j = len(b) - 1
    borrow = 0

    res = []

    while i >= 0:
        x = (ord(a[i]) - ord('0')) - borrow
        y = ord(b[j]) - ord('0') if j >= 0 else 0

        if x < y:
            x += 10
            borrow = 1
        else:
            borrow = 0

        res.append(chr(ord('0') + x - y))

        i -= 1
        j -= 1

    while len(res) > 1 and res[-1] == '0':
        res.pop()

    return ''.join(reversed(res))


def closestPalindrome(n):
    # If n itself is a palindrome, return it
    if isPalindrome(n):
        return n

    smaller = subtractOne(n)
    larger = addOne(n)

    # Find the closest palindrome smaller than n
    while not isPalindrome(smaller):
        smaller = subtractOne(smaller)

    # Find the closest palindrome greater than n
    while not isPalindrome(larger):
        larger = addOne(larger)

    diff1 = difference(n, smaller)
    diff2 = difference(n, larger)

    # Choose the closer palindrome.
    # If the difference is equal, choose the smaller one.
    if compare(diff1, diff2) <= 0:
        return smaller

    return larger


# Driver Code
if __name__ == "__main__":
    n = "9"
    print(closestPalindrome(n))
C#
using System;

class GFG {
    // Check whether a number is a palindrome
    static bool IsPalindrome(string s)
    {
        int i = 0, j = s.Length - 1;

        while (i < j) {
            if (s[i] != s[j])
                return false;

            i++;
            j--;
        }

        return true;
    }

    // Add 1 to a numeric string
    static string AddOne(string s)
    {
        char[] arr = s.ToCharArray();
        int i = arr.Length - 1;

        while (i >= 0 && arr[i] == '9') {
            arr[i] = '0';
            i--;
        }

        if (i < 0)
            return "1" + new string(arr);

        arr[i]++;
        return new string(arr);
    }

    // Subtract 1 from a numeric string
    static string SubtractOne(string s)
    {
        char[] arr = s.ToCharArray();
        int i = arr.Length - 1;

        while (i >= 0 && arr[i] == '0') {
            arr[i] = '9';
            i--;
        }

        if (i >= 0)
            arr[i]--;

        // Remove leading zeros
        int pos = 0;
        while (pos < arr.Length - 1 && arr[pos] == '0')
            pos++;

        return new string(arr, pos, arr.Length - pos);
    }

    // Compare two numeric strings
    static int Compare(string a, string b)
    {
        if (a.Length != b.Length)
            return a.Length < b.Length ? -1 : 1;

        if (a == b)
            return 0;

        return string.Compare(a, b,
                              StringComparison.Ordinal)
                < 0
            ? -1
            : 1;
    }

    // Find absolute difference of two numeric strings
    static string Difference(string a, string b)
    {
        if (Compare(a, b) < 0) {
            string temp = a;
            a = b;
            b = temp;
        }

        int i = a.Length - 1;
        int j = b.Length - 1;
        int borrow = 0;

        string res = "";

        while (i >= 0) {
            int x = (a[i] - '0') - borrow;
            int y = j >= 0 ? b[j] - '0' : 0;

            if (x < y) {
                x += 10;
                borrow = 1;
            }
            else {
                borrow = 0;
            }

            res += (char)('0' + (x - y));

            i--;
            j--;
        }

        while (res.Length > 1 && res[res.Length - 1] == '0')
            res = res.Substring(0, res.Length - 1);

        char[] arr = res.ToCharArray();
        Array.Reverse(arr);

        return new string(arr);
    }

    static string closestPalindrome(string n)
    {
        // If n itself is a palindrome, return it
        if (IsPalindrome(n))
            return n;

        string smaller = SubtractOne(n);
        string larger = AddOne(n);

        // Find the closest palindrome smaller than n
        while (!IsPalindrome(smaller))
            smaller = SubtractOne(smaller);

        // Find the closest palindrome greater than n
        while (!IsPalindrome(larger))
            larger = AddOne(larger);

        string diff1 = Difference(n, smaller);
        string diff2 = Difference(n, larger);

        // Choose the closer palindrome.
        // If the difference is equal, choose the smaller
        // one.
        if (Compare(diff1, diff2) <= 0)
            return smaller;

        return larger;
    }

    public static void Main()
    {
        string n = "9";
        Console.WriteLine(closestPalindrome(n));
    }
}
JavaScript
// Check whether a number is a palindrome
function isPalindrome(s)
{
    let i = 0;
    let j = s.length - 1;

    while (i < j) {
        if (s[i] !== s[j])
            return false;

        i++;
        j--;
    }

    return true;
}

// Add 1 to a numeric string
function addOne(s)
{
    let arr = s.split("");
    let i = arr.length - 1;

    while (i >= 0 && arr[i] === "9") {
        arr[i] = "0";
        i--;
    }

    if (i < 0)
        return "1" + arr.join("");

    arr[i] = String.fromCharCode(arr[i].charCodeAt(0) + 1);
    return arr.join("");
}

// Subtract 1 from a numeric string
function subtractOne(s)
{
    let arr = s.split("");
    let i = arr.length - 1;

    while (i >= 0 && arr[i] === "0") {
        arr[i] = "9";
        i--;
    }

    if (i >= 0)
        arr[i]
            = String.fromCharCode(arr[i].charCodeAt(0) - 1);

    // Remove leading zeros
    let pos = 0;
    while (pos < arr.length - 1 && arr[pos] === "0")
        pos++;

    return arr.slice(pos).join("");
}

// Compare two numeric strings
function compare(a, b)
{
    if (a.length !== b.length)
        return a.length < b.length ? -1 : 1;

    if (a === b)
        return 0;

    return a < b ? -1 : 1;
}

// Find absolute difference of two numeric strings
function difference(a, b)
{
    if (compare(a, b) < 0) {
        let temp = a;
        a = b;
        b = temp;
    }

    let i = a.length - 1;
    let j = b.length - 1;
    let borrow = 0;

    let res = [];

    while (i >= 0) {
        let x = (a.charCodeAt(i) - 48) - borrow;
        let y = j >= 0 ? b.charCodeAt(j) - 48 : 0;

        if (x < y) {
            x += 10;
            borrow = 1;
        }
        else {
            borrow = 0;
        }

        res.push(String.fromCharCode(48 + x - y));

        i--;
        j--;
    }

    while (res.length > 1 && res[res.length - 1] === "0")
        res.pop();

    return res.reverse().join("");
}

function closestPalindrome(n)
{
    // If n itself is a palindrome, return it
    if (isPalindrome(n))
        return n;

    let smaller = subtractOne(n);
    let larger = addOne(n);

    // Find the closest palindrome smaller than n
    while (!isPalindrome(smaller))
        smaller = subtractOne(smaller);

    // Find the closest palindrome greater than n
    while (!isPalindrome(larger))
        larger = addOne(larger);

    let diff1 = difference(n, smaller);
    let diff2 = difference(n, larger);

    // Choose the closer palindrome.
    // If the difference is equal, choose the smaller one.
    if (compare(diff1, diff2) <= 0)
        return smaller;

    return larger;
}

// Driver Code
let n = "9";
console.log(closestPalindrome(n));

Output
9

Time Complexity: O(k * d), k be the distance from n to the nearest palindrome and d be the number of digits.
Auxiliary Space: O(d)

[Expected Approach] Mirror and Adjust the First Half

The idea is to construct the closest palindrome directly instead of checking every number around n.

A palindrome is determined by its first half, so we take the first half of n and create three candidates by using the same half, one smaller half, and one larger half.

We then compare these candidates with n and choose the closest one, using the smaller palindrome to break ties.

  • Take the first half of n.
  • Construct a palindrome using the same half.
  • Decrease the half by 1 and construct the smaller palindrome.
  • Increase the half by 1 and construct the larger palindrome.
  • Handle boundary cases such as 1000 → 999 and 999 → 1001.
  • Compare all candidates and return the one with minimum difference; if tied, return the smaller palindrome.
C++
#include <bits/stdc++.h>
using namespace std;

// Create a palindrome using the first half
string makePalindrome(string half, int length)
{
    string temp = half;
    reverse(temp.begin(), temp.end());

    if (length % 2 == 0)
        return half + temp;

    // For odd length, do not duplicate the middle digit
    half.pop_back();
    return half + temp;
}

// Remove leading zeros
string trimLeadingZeros(string s)
{
    int i = 0;

    while (i < s.size() - 1 && s[i] == '0')
        i++;

    return s.substr(i);
}

// Add 1 to a numeric string
string addOne(string s)
{
    int i = s.size() - 1;
    int carry = 1;

    while (i >= 0 && carry)
    {
        int digit = (s[i] - '0') + carry;
        s[i] = char('0' + digit % 10);
        carry = digit / 10;
        i--;
    }

    if (carry)
        s = "1" + s;

    return s;
}

// Subtract 1 from a numeric string
string subtractOne(string s)
{
    int i = s.size() - 1;

    while (i >= 0 && s[i] == '0')
    {
        s[i] = '9';
        i--;
    }

    if (i >= 0)
        s[i]--;

    return trimLeadingZeros(s);
}

// Compare two numeric strings
int compare(string a, string b)
{
    a = trimLeadingZeros(a);
    b = trimLeadingZeros(b);

    if (a.size() != b.size())
        return a.size() < b.size() ? -1 : 1;

    if (a == b)
        return 0;

    return a < b ? -1 : 1;
}

// Find absolute difference of two numeric strings
string difference(string a, string b)
{
    if (compare(a, b) < 0)
        swap(a, b);

    int i = a.size() - 1;
    int j = b.size() - 1;
    int borrow = 0;

    string res = "";

    while (i >= 0)
    {
        int x = (a[i] - '0') - borrow;
        int y = (j >= 0 ? b[j] - '0' : 0);

        if (x < y)
        {
            x += 10;
            borrow = 1;
        }
        else
        {
            borrow = 0;
        }

        res += char('0' + (x - y));

        i--;
        j--;
    }

    while (res.size() > 1 && res.back() == '0')
        res.pop_back();

    reverse(res.begin(), res.end());

    return res;
}

string closestPalindrome(string &n)
{
    // If n itself is a palindrome, return it
    string rev = n;
    reverse(rev.begin(), rev.end());

    if (n == rev)
        return n;

    int length = n.size();

    // Take the first half of n
    string half = n.substr(0, (length + 1) / 2);

    // Candidate 1: Use the same half
    string same = makePalindrome(half, length);

    // Candidate 2: Use a smaller half
    string smallerHalf = subtractOne(half);
    string smaller;

    // Handle the case where the half loses a digit
    if (smallerHalf.size() < half.size())
        smaller = string(length - 1, '9');
    else
        smaller = makePalindrome(smallerHalf, length);

    // Candidate 3: Use a larger half
    string largerHalf = addOne(half);
    string larger;

    // Handle the case where the half gains a digit
    if (largerHalf.size() > half.size())
        larger = "1" + string(length - 1, '0') + "1";
    else
        larger = makePalindrome(largerHalf, length);

    // Find the differences from n
    string diffSame = difference(n, same);
    string diffSmaller = difference(n, smaller);
    string diffLarger = difference(n, larger);

    // Start with the smaller candidate
    string ans = smaller;
    string bestDiff = diffSmaller;

    // Check the same-half candidate
    if (compare(diffSame, bestDiff) < 0 || (compare(diffSame, bestDiff) == 0 && compare(same, ans) < 0))
    {
        ans = same;
        bestDiff = diffSame;
    }

    // Check the larger candidate
    if (compare(diffLarger, bestDiff) < 0 || (compare(diffLarger, bestDiff) == 0 && compare(larger, ans) < 0))
    {
        ans = larger;
    }

    return trimLeadingZeros(ans);
}

int main()
{
    string n = "9";
    cout << closestPalindrome(n) << endl;

    return 0;
}
Java
class GFG {

    // Create a palindrome using the first half
    static String makePalindrome(String half, int length)
    {
        String temp
            = new StringBuilder(half).reverse().toString();

        if (length % 2 == 0)
            return half + temp;

        // For odd length, do not duplicate the middle digit
        half = half.substring(0, half.length() - 1);
        return half + temp;
    }

    // Remove leading zeros
    static String trimLeadingZeros(String s)
    {
        int i = 0;

        while (i < s.length() - 1 && s.charAt(i) == '0')
            i++;

        return s.substring(i);
    }

    // Add 1 to a numeric string
    static String addOne(String s)
    {
        StringBuilder sb = new StringBuilder(s);
        int i = sb.length() - 1;
        int carry = 1;

        while (i >= 0 && carry > 0) {
            int digit = (sb.charAt(i) - '0') + carry;

            sb.setCharAt(i, (char)('0' + digit % 10));
            carry = digit / 10;
            i--;
        }

        if (carry > 0)
            sb.insert(0, '1');

        return sb.toString();
    }

    // Subtract 1 from a numeric string
    static String subtractOne(String s)
    {
        StringBuilder sb = new StringBuilder(s);
        int i = sb.length() - 1;

        while (i >= 0 && sb.charAt(i) == '0') {
            sb.setCharAt(i, '9');
            i--;
        }

        if (i >= 0)
            sb.setCharAt(i, (char)(sb.charAt(i) - 1));

        return trimLeadingZeros(sb.toString());
    }

    // Compare two numeric strings
    static int compare(String a, String b)
    {
        a = trimLeadingZeros(a);
        b = trimLeadingZeros(b);

        if (a.length() != b.length())
            return a.length() < b.length() ? -1 : 1;

        if (a.equals(b))
            return 0;

        return a.compareTo(b) < 0 ? -1 : 1;
    }

    // Find absolute difference of two numeric strings
    static String difference(String a, String b)
    {
        if (compare(a, b) < 0) {
            String temp = a;
            a = b;
            b = temp;
        }

        int i = a.length() - 1;
        int j = b.length() - 1;
        int borrow = 0;

        StringBuilder res = new StringBuilder();

        while (i >= 0) {
            int x = (a.charAt(i) - '0') - borrow;
            int y = (j >= 0 ? b.charAt(j) - '0' : 0);

            if (x < y) {
                x += 10;
                borrow = 1;
            }
            else {
                borrow = 0;
            }

            res.append((char)('0' + (x - y)));

            i--;
            j--;
        }

        while (res.length() > 1
               && res.charAt(res.length() - 1) == '0')
            res.deleteCharAt(res.length() - 1);

        return res.reverse().toString();
    }

    static String closestPalindrome(String n)
    {
        // If n itself is a palindrome, return it
        String rev
            = new StringBuilder(n).reverse().toString();

        if (n.equals(rev))
            return n;

        int length = n.length();

        // Take the first half of n
        String half = n.substring(0, (length + 1) / 2);

        // Candidate 1: Use the same half
        String same = makePalindrome(half, length);

        // Candidate 2: Use a smaller half
        String smallerHalf = subtractOne(half);
        String smaller;

        // Handle the case where the half loses a digit
        if (smallerHalf.length() < half.length())
            smaller = "9".repeat(length - 1);
        else
            smaller = makePalindrome(smallerHalf, length);

        // Candidate 3: Use a larger half
        String largerHalf = addOne(half);
        String larger;

        // Handle the case where the half gains a digit
        if (largerHalf.length() > half.length())
            larger = "1"
                     + "0".repeat(length - 1) + "1";
        else
            larger = makePalindrome(largerHalf, length);

        // Find the differences from n
        String diffSame = difference(n, same);
        String diffSmaller = difference(n, smaller);
        String diffLarger = difference(n, larger);

        // Start with the smaller candidate
        String ans = smaller;
        String bestDiff = diffSmaller;

        // Check the same-half candidate
        if (compare(diffSame, bestDiff) < 0
            || (compare(diffSame, bestDiff) == 0
                && compare(same, ans) < 0)) {
            ans = same;
            bestDiff = diffSame;
        }

        // Check the larger candidate
        if (compare(diffLarger, bestDiff) < 0
            || (compare(diffLarger, bestDiff) == 0
                && compare(larger, ans) < 0)) {
            ans = larger;
        }

        return trimLeadingZeros(ans);
    }

    public static void main(String[] args)
    {
        String n = "9";
        System.out.println(closestPalindrome(n));
    }
}
Python
# Create a palindrome using the first half
def makePalindrome(half, length):
    temp = half[::-1]

    if length % 2 == 0:
        return half + temp

    # For odd length, do not duplicate the middle digit
    half = half[:-1]
    return half + temp


# Remove leading zeros
def trimLeadingZeros(s):
    i = 0

    while i < len(s) - 1 and s[i] == '0':
        i += 1

    return s[i:]


# Add 1 to a numeric string
def addOne(s):
    s = list(s)
    i = len(s) - 1
    carry = 1

    while i >= 0 and carry:
        digit = (ord(s[i]) - ord('0')) + carry

        s[i] = chr(ord('0') + digit % 10)
        carry = digit // 10
        i -= 1

    if carry:
        s.insert(0, '1')

    return ''.join(s)


# Subtract 1 from a numeric string
def subtractOne(s):
    s = list(s)
    i = len(s) - 1

    while i >= 0 and s[i] == '0':
        s[i] = '9'
        i -= 1

    if i >= 0:
        s[i] = chr(ord(s[i]) - 1)

    return trimLeadingZeros(''.join(s))


# Compare two numeric strings
def compare(a, b):
    a = trimLeadingZeros(a)
    b = trimLeadingZeros(b)

    if len(a) != len(b):
        return -1 if len(a) < len(b) else 1

    if a == b:
        return 0

    return -1 if a < b else 1


# Find absolute difference of two numeric strings
def difference(a, b):
    if compare(a, b) < 0:
        a, b = b, a

    i = len(a) - 1
    j = len(b) - 1
    borrow = 0
    res = []

    while i >= 0:
        x = (ord(a[i]) - ord('0')) - borrow
        y = ord(b[j]) - ord('0') if j >= 0 else 0

        if x < y:
            x += 10
            borrow = 1
        else:
            borrow = 0

        res.append(chr(ord('0') + x - y))

        i -= 1
        j -= 1

    while len(res) > 1 and res[-1] == '0':
        res.pop()

    return ''.join(reversed(res))


def closestPalindrome(n):
    # If n itself is a palindrome, return it
    if n == n[::-1]:
        return n

    length = len(n)

    # Take the first half of n
    half = n[:(length + 1) // 2]

    # Candidate 1: Use the same half
    same = makePalindrome(half, length)

    # Candidate 2: Use a smaller half
    smallerHalf = subtractOne(half)

    # Handle the case where the half loses a digit
    if len(smallerHalf) < len(half):
        smaller = '9' * (length - 1)
    else:
        smaller = makePalindrome(smallerHalf, length)

    # Candidate 3: Use a larger half
    largerHalf = addOne(half)

    # Handle the case where the half gains a digit
    if len(largerHalf) > len(half):
        larger = '1' + '0' * (length - 1) + '1'
    else:
        larger = makePalindrome(largerHalf, length)

    # Find the differences from n
    diffSame = difference(n, same)
    diffSmaller = difference(n, smaller)
    diffLarger = difference(n, larger)

    # Start with the smaller candidate
    ans = smaller
    bestDiff = diffSmaller

    # Check the same-half candidate
    if compare(diffSame, bestDiff) < 0 or \
       (compare(diffSame, bestDiff) == 0 and
            compare(same, ans) < 0):
        ans = same
        bestDiff = diffSame

    # Check the larger candidate
    if compare(diffLarger, bestDiff) < 0 or \
       (compare(diffLarger, bestDiff) == 0 and
            compare(larger, ans) < 0):
        ans = larger

    return trimLeadingZeros(ans)


# Driver Code
if __name__ == "__main__":
    n = "9"
    print(closestPalindrome(n))
C#
using System;

class GFG {
    // Create a palindrome using the first half
    static string MakePalindrome(string half, int length)
    {
        char[] tempArr = half.ToCharArray();
        Array.Reverse(tempArr);

        string temp = new string(tempArr);

        if (length % 2 == 0)
            return half + temp;

        // For odd length, do not duplicate the middle digit
        half = half.Substring(0, half.Length - 1);

        return half + temp;
    }

    // Remove leading zeros
    static string TrimLeadingZeros(string s)
    {
        int i = 0;

        while (i < s.Length - 1 && s[i] == '0')
            i++;

        return s.Substring(i);
    }

    // Add 1 to a numeric string
    static string AddOne(string s)
    {
        char[] arr = s.ToCharArray();
        int i = arr.Length - 1;
        int carry = 1;

        while (i >= 0 && carry > 0) {
            int digit = (arr[i] - '0') + carry;

            arr[i] = (char)('0' + digit % 10);
            carry = digit / 10;
            i--;
        }

        if (carry > 0)
            return "1" + new string(arr);

        return new string(arr);
    }

    // Subtract 1 from a numeric string
    static string SubtractOne(string s)
    {
        char[] arr = s.ToCharArray();
        int i = arr.Length - 1;

        while (i >= 0 && arr[i] == '0') {
            arr[i] = '9';
            i--;
        }

        if (i >= 0)
            arr[i]--;

        return TrimLeadingZeros(new string(arr));
    }

    // Compare two numeric strings
    static int Compare(string a, string b)
    {
        a = TrimLeadingZeros(a);
        b = TrimLeadingZeros(b);

        if (a.Length != b.Length)
            return a.Length < b.Length ? -1 : 1;

        if (a == b)
            return 0;

        return string.Compare(a, b,
                              StringComparison.Ordinal)
                < 0
            ? -1
            : 1;
    }

    // Find absolute difference of two numeric strings
    static string Difference(string a, string b)
    {
        if (Compare(a, b) < 0) {
            string temp = a;
            a = b;
            b = temp;
        }

        int i = a.Length - 1;
        int j = b.Length - 1;
        int borrow = 0;

        string res = "";

        while (i >= 0) {
            int x = (a[i] - '0') - borrow;
            int y = j >= 0 ? b[j] - '0' : 0;

            if (x < y) {
                x += 10;
                borrow = 1;
            }
            else {
                borrow = 0;
            }

            res += (char)('0' + x - y);

            i--;
            j--;
        }

        while (res.Length > 1
               && res[res.Length - 1] == '0') {
            res = res.Substring(0, res.Length - 1);
        }

        char[] arr = res.ToCharArray();
        Array.Reverse(arr);

        return new string(arr);
    }

    static string closestPalindrome(string n)
    {
        // If n itself is a palindrome, return it
        char[] revArr = n.ToCharArray();
        Array.Reverse(revArr);

        if (n == new string(revArr))
            return n;

        int length = n.Length;

        // Take the first half of n
        string half = n.Substring(0, (length + 1) / 2);

        // Candidate 1: Use the same half
        string same = MakePalindrome(half, length);

        // Candidate 2: Use a smaller half
        string smallerHalf = SubtractOne(half);
        string smaller;

        // Handle the case where the half loses a digit
        if (smallerHalf.Length < half.Length)
            smaller = new string('9', length - 1);
        else
            smaller = MakePalindrome(smallerHalf, length);

        // Candidate 3: Use a larger half
        string largerHalf = AddOne(half);
        string larger;

        // Handle the case where the half gains a digit
        if (largerHalf.Length > half.Length)
            larger
                = "1" + new string('0', length - 1) + "1";
        else
            larger = MakePalindrome(largerHalf, length);

        // Find the differences from n
        string diffSame = Difference(n, same);
        string diffSmaller = Difference(n, smaller);
        string diffLarger = Difference(n, larger);

        // Start with the smaller candidate
        string ans = smaller;
        string bestDiff = diffSmaller;

        // Check the same-half candidate
        if (Compare(diffSame, bestDiff) < 0
            || (Compare(diffSame, bestDiff) == 0
                && Compare(same, ans) < 0)) {
            ans = same;
            bestDiff = diffSame;
        }

        // Check the larger candidate
        if (Compare(diffLarger, bestDiff) < 0
            || (Compare(diffLarger, bestDiff) == 0
                && Compare(larger, ans) < 0)) {
            ans = larger;
        }

        return TrimLeadingZeros(ans);
    }

    public static void Main()
    {
        string n = "9";
        Console.WriteLine(closestPalindrome(n));
    }
}
JavaScript
// Create a palindrome using the first half
function makePalindrome(half, length)
{
    let temp = half.split("").reverse().join("");

    if (length % 2 === 0)
        return half + temp;

    // For odd length, do not duplicate the middle digit
    half = half.slice(0, -1);

    return half + temp;
}

// Remove leading zeros
function trimLeadingZeros(s)
{
    let i = 0;

    while (i < s.length - 1 && s[i] === "0")
        i++;

    return s.slice(i);
}

// Add 1 to a numeric string
function addOne(s)
{
    let arr = s.split("");
    let i = arr.length - 1;
    let carry = 1;

    while (i >= 0 && carry) {
        let digit = (arr[i].charCodeAt(0) - 48) + carry;

        arr[i] = String.fromCharCode(48 + digit % 10);
        carry = Math.floor(digit / 10);
        i--;
    }

    if (carry)
        arr.unshift("1");

    return arr.join("");
}

// Subtract 1 from a numeric string
function subtractOne(s)
{
    let arr = s.split("");
    let i = arr.length - 1;

    while (i >= 0 && arr[i] === "0") {
        arr[i] = "9";
        i--;
    }

    if (i >= 0)
        arr[i]
            = String.fromCharCode(arr[i].charCodeAt(0) - 1);

    return trimLeadingZeros(arr.join(""));
}

// Compare two numeric strings
function compare(a, b)
{
    a = trimLeadingZeros(a);
    b = trimLeadingZeros(b);

    if (a.length !== b.length)
        return a.length < b.length ? -1 : 1;

    if (a === b)
        return 0;

    return a < b ? -1 : 1;
}

// Find absolute difference of two numeric strings
function difference(a, b)
{
    if (compare(a, b) < 0) {
        let temp = a;
        a = b;
        b = temp;
    }

    let i = a.length - 1;
    let j = b.length - 1;
    let borrow = 0;

    let res = [];

    while (i >= 0) {
        let x = (a.charCodeAt(i) - 48) - borrow;
        let y = j >= 0 ? b.charCodeAt(j) - 48 : 0;

        if (x < y) {
            x += 10;
            borrow = 1;
        }
        else {
            borrow = 0;
        }

        res.push(String.fromCharCode(48 + x - y));

        i--;
        j--;
    }

    while (res.length > 1 && res[res.length - 1] === "0")
        res.pop();

    return res.reverse().join("");
}

function closestPalindrome(n)
{
    // If n itself is a palindrome, return it
    let rev = n.split("").reverse().join("");

    if (n === rev)
        return n;

    let length = n.length;

    // Take the first half of n
    let half = n.slice(0, Math.floor((length + 1) / 2));

    // Candidate 1: Use the same half
    let same = makePalindrome(half, length);

    // Candidate 2: Use a smaller half
    let smallerHalf = subtractOne(half);
    let smaller;

    // Handle the case where the half loses a digit
    if (smallerHalf.length < half.length)
        smaller = "9".repeat(length - 1);
    else
        smaller = makePalindrome(smallerHalf, length);

    // Candidate 3: Use a larger half
    let largerHalf = addOne(half);
    let larger;

    // Handle the case where the half gains a digit
    if (largerHalf.length > half.length)
        larger = "1" +
                 "0".repeat(length - 1) + "1";
    else
        larger = makePalindrome(largerHalf, length);

    // Find the differences from n
    let diffSame = difference(n, same);
    let diffSmaller = difference(n, smaller);
    let diffLarger = difference(n, larger);

    // Start with the smaller candidate
    let ans = smaller;
    let bestDiff = diffSmaller;

    // Check the same-half candidate
    if (compare(diffSame, bestDiff) < 0
        || (compare(diffSame, bestDiff) === 0
            && compare(same, ans) < 0)) {
        ans = same;
        bestDiff = diffSame;
    }

    // Check the larger candidate
    if (compare(diffLarger, bestDiff) < 0
        || (compare(diffLarger, bestDiff) === 0
            && compare(larger, ans) < 0)) {
        ans = larger;
    }

    return trimLeadingZeros(ans);
}

// Driver Code
let n = "9";
console.log(closestPalindrome(n));

Output
9

Time Complexity: O(d), d is the number of digits in n.
Auxiliary Space: O(d)

Comment