题目来自LeetCode:
https://leetcode-cn.com/problems/find-the-closest-palindrome/
题目:
给定一个整数n,找到与它最近的回文数(不包括自身)。
“最近的”定义为两个整数差的绝对值最小。
eg.
输入: "123"
输出: "121"
注意:
n是由字符串表示的正整数。
如果有多个结果,返回最小的那个。
保留高位数字,改变低位数字,利用前半部分n_left(高位数)做镜像生成回文数
值最接近的回文数可能为n_left、n_left+1或n_left-1产生的回文数,三者比较即可
特殊情况单独处理
截取n_left时分n的长度为奇数和偶数两种情况
参考:
https://leetcode-cn.com/problems/find-the-closest-palindrome/solution/zhao-gui-lu-by-heng-29/
https://leetcode-cn.com/problems/find-the-closest-palindrome/solution/jing-xiang-dui-bi-by-dui-fang-xian-ru-chen-si/
def NearestPalindromic(n):
try:
n_int = int(n)
if n_int < 0:
print('n小于0!')
return None
except:
print('输入n应为字符串表示的正整数!')
return None
lenn = len(n)
lenn_half = lenn // 2
# 特殊情况:只有一位数
if lenn_half == 0:
return '1' if n == '0' else str(n_int-1)
# 特殊情况:开头1,中间若干个0,末尾一个数字
if n[0] == '1' and not any([int(x) for x in n[1:-1]]):
# 若最后一位为0或1,结果应全由9构成;若最后一位为其他,则将最后一位改为1即可
if n[-1] in ['0', '1']:
return '9' * (lenn-1)
else:
return n[:-1] + '1'
# 特殊情况:全是9
if not any([int(x)-9 for x in n]):
return str(n_int+2)
# n为偶数位
if lenn % 2 == 0:
n_left = n[:lenn_half]
tgt_n = n_left + n_left[::-1] # 原数反转
tmp = str(int(n_left)-1)
tgt_sml = tmp + tmp[::-1] # 小的目标值
tmp = str(int(n_left)+1)
tgt_big = tmp + tmp[::-1] # 大的目标值
else:
n_left = n[:lenn_half]
tgt_n = n_left + n[lenn_half] + n_left[::-1]
tmp = str(int(n[:lenn_half+1])-1)
tgt_sml = tmp + tmp[:-1][::-1]
tmp = str(int(n[:lenn_half+1])+1)
tgt_big = tmp + tmp[:-1][::-1]
# 从大到小排除其他两个结果
ans = tgt_big
for t in [tgt_n, tgt_sml]:
dif = abs(int(t)-n_int)
if dif > 0 and dif <= abs(int(ans)-n_int):
ans = t
return ans
if __name__ == '__main__':
n = '123'
print(n+': ——>', NearestPalindromic(n))
n = '1283'
print(n+': ——>', NearestPalindromic(n))
欢迎关注公众号:一本正经d胡说