|
| 1 | +/** |
| 2 | + * 564. Find the Closest Palindrome |
| 3 | + * https://leetcode.com/problems/find-the-closest-palindrome/ |
| 4 | + * Difficulty: Hard |
| 5 | + * |
| 6 | + * Given a string n representing an integer, return the closest integer (not including itself), |
| 7 | + * which is a palindrome. If there is a tie, return the smaller one. |
| 8 | + * |
| 9 | + * The closest is defined as the absolute difference minimized between two integers. |
| 10 | + */ |
| 11 | + |
| 12 | +/** |
| 13 | + * @param {string} n |
| 14 | + * @return {string} |
| 15 | + */ |
| 16 | +var nearestPalindromic = function(n) { |
| 17 | + const num = BigInt(n); |
| 18 | + |
| 19 | + if (num <= 10n) return String(num - 1n); |
| 20 | + if (num === 11n) return '9'; |
| 21 | + if (n === '1' + '0'.repeat(n.length - 1)) return String(num - 1n); |
| 22 | + if (n === '9'.repeat(n.length)) return String(num + 2n); |
| 23 | + |
| 24 | + const leftHalf = n.slice(0, Math.ceil(n.length / 2)); |
| 25 | + const leftNum = BigInt(leftHalf); |
| 26 | + const candidates = [ |
| 27 | + String(10n ** BigInt(n.length - 1) - 1n), |
| 28 | + createPalindrome(leftNum - 1n, n.length), |
| 29 | + createPalindrome(leftNum, n.length), |
| 30 | + createPalindrome(leftNum + 1n, n.length), |
| 31 | + String(10n ** BigInt(n.length) + 1n) |
| 32 | + ].filter(x => x !== n); |
| 33 | + |
| 34 | + return candidates.reduce((min, curr) => { |
| 35 | + const currDiff = BigInt(curr) > num ? BigInt(curr) - num : num - BigInt(curr); |
| 36 | + const minDiff = BigInt(min) > num ? BigInt(min) - num : num - BigInt(min); |
| 37 | + return currDiff < minDiff |
| 38 | + ? curr |
| 39 | + : currDiff === minDiff |
| 40 | + ? (curr < min ? curr : min) |
| 41 | + : min; |
| 42 | + }); |
| 43 | + |
| 44 | + function createPalindrome(left, length) { |
| 45 | + const s = String(left); |
| 46 | + return length % 2 === 0 |
| 47 | + ? s + s.split('').reverse().join('') |
| 48 | + : s + s.slice(0, -1).split('').reverse().join(''); |
| 49 | + } |
| 50 | +}; |
0 commit comments