Back to all solutions
#564 - Find the Closest Palindrome
Problem Description
Given a string n representing an integer, return the closest integer (not including itself), which is a palindrome. If there is a tie, return the smaller one.
The closest is defined as the absolute difference minimized between two integers.
Solution
/**
* @param {string} n
* @return {string}
*/
var nearestPalindromic = function(n) {
const num = BigInt(n);
if (num <= 10n) return String(num - 1n);
if (num === 11n) return '9';
if (n === '1' + '0'.repeat(n.length - 1)) return String(num - 1n);
if (n === '9'.repeat(n.length)) return String(num + 2n);
const leftHalf = n.slice(0, Math.ceil(n.length / 2));
const leftNum = BigInt(leftHalf);
const candidates = [
String(10n ** BigInt(n.length - 1) - 1n),
createPalindrome(leftNum - 1n, n.length),
createPalindrome(leftNum, n.length),
createPalindrome(leftNum + 1n, n.length),
String(10n ** BigInt(n.length) + 1n)
].filter(x => x !== n);
return candidates.reduce((min, curr) => {
const currDiff = BigInt(curr) > num ? BigInt(curr) - num : num - BigInt(curr);
const minDiff = BigInt(min) > num ? BigInt(min) - num : num - BigInt(min);
return currDiff < minDiff
? curr
: currDiff === minDiff
? (curr < min ? curr : min)
: min;
});
function createPalindrome(left, length) {
const s = String(left);
return length % 2 === 0
? s + s.split('').reverse().join('')
: s + s.slice(0, -1).split('').reverse().join('');
}
};