来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-the-closest-palindrome
题目描述
给定一个表示整数的字符串 n ,返回与它最近的回文整数(不包括自身)。如果不止一个,返回较小的那个。
“最近的”定义为两个整数差的绝对值最小。
示例 1: 输入: n = "123" 输出: "121" 示例 2: 输入: n = "1" 输出: "0" 解释: 0 和 2是最近的回文,但我们返回最小的,也就是 0。 提示: 1 <= n.length <= 18 n 只由数字组成 n 不含前导 0 n 代表在 [1, 1018 - 1] 范围内的整数
解题思路
一道十分困难的脑经急转弯题。。
关键要想到,每次将字符串前半部分镜像到后半部分得到的数字比将后半部分复制到前半部分构成的字符串更加接近原数。
所以可以确定候选的一些数字分别是由前半部分数字多1,前半部分数字,前半部分数字减1,999……999, 100……001之中。
将这五个数枚举出来,依次判断出非本身外最接近原数的数即可。
代码展示
class Solution { public: string nearestPalindromic(string n) { int iN = n.size(); long lSelf = stol(n); vector<long> vlN = {(long)pow(10, iN - 1) - 1, (long)pow(10, iN) + 1}; string strPrefix = n.substr(0, (iN + 1) / 2); long lPrefix = stol(strPrefix); for(long i: {lPrefix - 1, lPrefix, lPrefix + 1}) { string strTemp = to_string(i); string strCandidate = strTemp + string(strTemp.rbegin() + (iN & 1), strTemp.rend()); vlN.push_back(stol(strCandidate)); } long lRet = -1; for(auto iter: vlN) { if(iter != lSelf) { if(abs(lSelf - iter) < abs(lSelf - lRet) || abs(lSelf - iter) == abs(lSelf - lRet) && iter < lRet) { lRet = iter; } } } return to_string(lRet); } };
运行结果