题意:
给一个数字n 求离n最近(且不等)的回文串 存在多个答案返回最小的
首先很容易想到
将数字分为两段,如 12345 -> 123/45,然后将后半段根据前面的进行镜像重置 123/45 -> 12321
那,如果数字刚好是回文串,就把前半段-1就好了
但是存在以下例外,就是当前半段 +1 或 -1 就会造成进位
10999
10901-10999 = -98
11011 - 10999 = -12
可以发现是因为9存在的进位,同样0也可能,所以对前半段进行 +1 和 -1 两种处理,然后选择差比较小的那个。
代码写的比较乱= =
class Solution { public: string nearestPalindromic(string n) { typedef long long ll; if (n == "10" || n == "11") return "9"; int l = n.size(); int half = (l + 1) / 2; string left = n.substr(0, half); string right = n.substr(half); // 情况1: 直接镜像翻转 string ans1 = (l & 1) ? left + rev_str(left).substr(1) : left + rev_str(left); // 如果和原数字相同则不可用 ll diff1 = ans1 == n ? stoll(n) : abs(stoll(ans1) - stoll(n)); // 情况2: -1 string left_sub_1 = to_string(stoll(left) - 1); string rleft_sub_1 = rev_str(left_sub_1); string ans2; if (left_sub_1.size() < half) { ans2 = (l & 1) ? left_sub_1 + rleft_sub_1 : left_sub_1 + "9" + rleft_sub_1; } else { ans2 = (l & 1) ? left_sub_1 + rleft_sub_1.substr(1) : left_sub_1 + rleft_sub_1; } ll diff2 = abs(stoll(ans2) - stoll(n)); // 情况3: +1 string left_add_1 = to_string(stoll(left) + 1); string rleft_add_1 = rev_str(left_add_1); string ans3; if (left_add_1.size() > half) { ans3 = (l & 1) ? left_add_1 + rleft_add_1.substr(2) : left_add_1 + rleft_add_1.substr(1); } else { ans3 = (l & 1) ? left_add_1 + rleft_add_1.substr(1) : left_add_1 + rleft_add_1; } ll diff3 = abs(stoll(ans3) - stoll(n)); if (diff2 <= diff1 && diff2 <= diff3) return ans2; if (diff1 <= diff2 && diff1 <= diff3) return ans1; return ans3; } string rev_str(string a) { string b(a); reverse(b.begin(), b.end()); return b; } };