564.寻找最近的回文数
力扣题目链接:https://leetcode-cn.com/problems/find-the-closest-palindrome/
给定一个表示整数的字符串 $n$ ,返回与它最近的回文整数(不包括自身)。如果不止一个,返回较小的那个。
“最近的”定义为两个整数差的绝对值最小。
示例 1:
1 |
|
示例 2:
1 |
|
提示:
- $1 \leq n.length \leq 18$
- $n$ 只由数字组成
- $n$ 不含前导 $0$
- $n$ 代表在 $[1, 10^{18} - 1]$ 范围内的整数
思路
本题主要思路就是贪心。要想使修改后和修改前差别尽可能小,最容易想到的就是优先修改低位的数字。
但是回文串中,低位的修改可能会导致高位同步修改,因此,最小代价的改动就是修改中间的值。
比如数字 $222$ 本身就是回文串,要变成与它绝对值之差最小的回文串,如果把最低位的 $2$ 修改为 $1$,那么最高位的 $2$ 也要相应地修改为 $1$,因此 $222$ 就变成了 $121$ ,$diff=abs(121-222)=101$ 。但是如果我们优先修改中间的值,把十位的 $2$ 修改为 $1$ ,$222$ 就会变成 $212$ , $diff=abs(212-222)=10$ 。
总之,尽可能优先地修改中间的值即可。修改完中间的值后,只需要把后半部分变成前半部分的对称即可。因为是尽可能小地改动,所以我们只需要考虑 $前半部分-1$ 、 $前半部分不变$ 、 $前半部分+1$ 这 $3$ 种情况,并把后半部分变成前半部分的对称即可。
特殊情况:
当给定数字本身就是个位数时,直接 $原数字-1$ 即可。
存在一些特殊的数字,采用上述贪心策略无法得到最优解。
例如 $999$ ,按照上述贪心策略可能会考虑 前半部分 $99+1=100$ 的情况,这样前后做对称就变成了 $100001$ ,显然 $999$ 变成 $1001$ 才是更优解。同理,$10023$ 按上述策略会变成 $999$ ,但其实 $9999$ 才是最优解。
这两种情况是由“前半部分±1后数字位数发生变化”导致的,我们在考虑最优解的时候,把形如 $100..001$ 、 $99..99$ 的数字也考虑进去即可。
AC代码
C++
1 |
|
同步发文于CSDN,原创不易,转载请附上原文链接哦~
Tisfy:https://letmefly.blog.csdn.net/article/details/123254172