📜  下一个较高的回文数,使用相同的数字集(1)

📅  最后修改于: 2023-12-03 14:48:48.619000             🧑  作者: Mango

寻找下一个较高的回文数

问题描述

给定一个正整数,求比这个数大的下一个回文数(即正着看和倒着看都一样的数),使用相同的数字集。

解题思路

首先,我们需要判断一个数是否为回文数。假设 $n$ 是一个 $k$ 位数,判断方法如下:

  1. 对于 $i \in [1,k/2]$,判断第 $i$ 位和第 $k-i+1$ 位上的数字是否相同,如果存在不同,则 $n$ 不是回文数;
  2. 如果所有位都相同,则 $n$ 是回文数。

接下来,我们需要求下一个较高的回文数。

假设给定数是 $n$,它的下一个回文数为 $m$。有以下情况:

  1. 如果 $n$ 所有位上的数字都是 9,则 $m$ 的位数比 $n$ 大 1,且所有位为 0,但首尾两位为 1。
  2. 如果 $n$ 所有位上的数字都不是 9,则我们只需要将 $n$ 的前半截镜像到后半截上,即得到 $m$,例如:
n = 123456
m = 123321
(注:对于位数为奇数的情况,中间的数字不需要镜像,例如 12321 的下一个回文数是 12421)
  1. 如果 $n$ 的前半截比后半截大,例如 $n=$ 1234 56,此时我们只需要将前半截镜像到后半截上,得到 1234 21 小于 $n$,这时需要将中间一位的数字加 1,得到下一个回文数 1235 21。
代码实现
def is_palindrome(num):
    s = str(num)
    for i in range(len(s) // 2):
        if s[i] != s[-i-1]:
            return False
    return True

def next_palindrome(num):
    s = str(num)
    n = len(s)
    if s == '9' * n:
        return int('1' + '0' * n + '1')
    if n % 2 == 0:
        left = s[:n//2]
        right = left[::-1]
        if right > s[n//2:]:
            return int(left + right)
        else:
            left = str(int(left)+1)
            right = left[::-1]
            return int(left + right)
    else:
        left = s[:n//2]
        mid = s[n//2]
        right = left[::-1]
        if right > s[n//2+1:]:
            return int(left + mid + right)
        else:
            left = str(int(left+mid)+1)
            right = left[:-1][::-1]
            return int(left + right)
测试案例
assert next_palindrome(12321) == 12421
assert next_palindrome(123456) == 123321
assert next_palindrome(1234567) == 1235321
assert next_palindrome(9999) == 10001
assert next_palindrome(999) == 1001
assert next_palindrome(9) == 11