寻找最近的回文数-python

leetCode第564题 寻找最近的回文数
链接: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] 范围内的整数

本题的难度为困难,但这不是说这个题解法很难,难在找全所有的条件以及它的代码实现。
我们来分析一下他的所有条件。
①对于一般条件,我们只要构造出他的回文数字就行,如123的回文数是121,要保证者相差最小,那么肯定是高位要一致,所以肯定是从前往后替换,而不是构造323,只要放置两个指针在首和尾,不断替换,但python提供了列表的骚操作,可以快速替换。
②如果这个数本身就是回文数应该怎么处理,如121。这时应该让中间数+1或者-1,构造111或者132。为什么要构造-1的呢,当碰到999这种应该构造1001而不是989。
③如果是898这种中间+1变成10的话要进行进位处理,但如果是999,要进位的数又发生进位的话,直接构造 1 0 n 10^n 10n+1变成1001,n为原来数的长度。
④如果碰到202这种,中间-1就要借位处理,构造成191。但如果是101,要借位的话,原本的长度就会发生变化,直接构造 1 0 n − 1 10^n-1 10n1,变为99,n为原数的长度。
⑤碰到10或者11直接返回9。因为10一旦构造回文数就是11,11的话构造的话就是22,因为<10的数本身就是回文数,应该直接返回9。10,11构造会是个两位数,所以是一种特殊情况。

分享一种很没技术含量的写法

## python3
class Solution:
    def nearestPalindromic(self, n: str) -> str:
        str1 = n
        if int(n) > 0 and int(n) < 11:  ## 特殊情况
            return str(int(n)-1)
        if int(n) == 11:
            return '9'
        str2 = [i for i in n]
        str3 = str2[::-1]
        mid = int(len(str2) / 2)
        str2[mid:] = str3[mid:]
        str3 = [i for i in str2]
        str3[mid] = str(int(str3[mid]) + 1)
        str4 = [i for i in str2]
        str4[mid] = str(int(str4[mid]) - 1)
        if str3[mid] == "10":    ## 处理会发生进位的情况
            x = mid-1
            while str3[x] == '9' and x != 0:
                x -= 1
            if x == 0:
                str3 = [i for i in str(10**len(str3)+1)]
            else:
                str3[x] = str(int(str3[x]) +1)
                str3[x+1:mid+1] = ['0' for i in range(mid-x)]
                temp = str3[::-1]
                str3[mid:] = temp[mid:]
        temp = str3[::-1]
        str3[:mid] = temp[:mid]
        if str4[mid] == '-1':   ## 处理发生借位的情况
            x = mid - 1
            while str4[x] == '0' and x != 0:
                x -= 1
            if x == 0 and str4[x] == '1':
                str4 = [i for i in str(10 ** (len(str4)-1) - 1)]
            else:
                str4[x] = str(int(str4[x])-1)
                str4[x+1:mid+1] = ['9' for i in range(mid-x)]
                temp = str4[::-1]
                str4[mid:] = temp[mid:]
        temp = str4[::-1]
        str4[:mid] = temp[:mid]
        res = []
        res.append(int(''.join(str2)))
        res.append(int(''.join(str3)))
        res.append(int(''.join(str4)))
        min = 10**18
        n = int(''.join(n))
        index = 0
        for i in range(len(res)):
            temp =res[i]
            if temp == n:
                continue
            else:
                x = abs(n-temp)
                if x == min and temp < res[index]:   ## 若间隔一样大,应该选择值比较小的那个
                    index = i
                elif abs(n-temp) < min:
                    min = abs(n-temp)
                    index = i
        return  str(res[index])

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

unseven

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值