题目
思路
数学问题
首先对于一个数字,如何将其变为回文数字,最简单的数字就是以最中间的元素为中心,将低位的数字变为对应位置的高位数字。例如12356,将个位与十位分别变为1和2形成回文数字12321。但这样操作不一定能够得到最近的回文数。
- 当构造的回文整数大于原数时,例如99211,按照上述方法得到的回文数为99299,但实际上99199距离99211更近。即需要将中间元素减1后再进行回文操作。
- 当构造的回文整数小于原数时,例如11299,按照上述方法得到的回文数为11211,但实际上11299距离11311更近。即需要将中间元素加1后再进行回文操作。
- 当给定的数字就是回文数字时,不能输出该数字,需要找到距离该数字最近的回文数。
注意
- 当给定数字只有一位时,因为一位数字一定是回文数,所以直接返回该数字减1后的字符串格式。
- 例如数字10000它的最近回文数为9999,与原始数字位数不同,例如数字9999它的最近回文数为10001,与原始数字位数不同。
根据上述分析,一个数字的最近回文数只能在以下情况中:
- 比原始数字少一位的全9数字,例如999
- 比原始数字多一位的中间全0两边为1数字,例如10001
- 原始数字直接进行回文处理,例如12322
- 原始数字进行缩小后回文处理,例如99211
- 原始数字进行增大后回文处理,例如11299
另外,因为题目要求需要找到最近且最小的回文数,所以再排序的时候需要考虑最近与最小,所以排序使用二位序号,第一个序号表示当前回文数语原始数字的距离,第二个序号表示原始数字。在min函数进行排序时,首先对元组的第一个元素进行排序,若第一个元素相同则比较第二个元素,最终得到最近最小回文数。
Python3代码
lambda函数输入参数x,输出一个元组(a,b)。a是当前数字语原始数字的距离,b是当前数字。特别地当当前数字于原始数字相同时,abs(int(x) - int(n))等于0,则第一个元素被置为999999。
def nearestPalindromic(self, n: str) -> str:
l = len(n)
if l == 1: return str(int(n) - 1)
s = n[: l // 2 + l % 2]
s1 = str(int(s) - 1)
s2 = str(int(s) + 1)
return min('9' * (l - 1),
'1' + '0' * (l - 1) + '1',
s + s[-1 - l % 2::-1],
s1 + s1[-1 - l % 2::-1],
s2 + s2[-1 - l % 2::-1],
key=lambda x: (abs(int(x) - int(n)) or 999999, int(x)))