一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第21天,点击查看活动详情。
给定一个表示整数的字符串
n,返回与它最近的回文整数(不包括自身)。如果不止一个,返回较小的那个。“最近的”定义为两个整数差的绝对值最小。
本题求的是最近的回文数,何为最近?题目中给出了明确的说法,“最近的”定义为两个整数差的绝对值最小。
举个例子,123最近的回文数为121,因为比123小的回文数为121,比123大的回文数为131,而121与123的差绝对值更小,所以应该得到的结果是121。
先简单思考一下这个问题,对于任意一个数,我们可以先将其直接转为一个回文数,例如:
12345
对于这个数,可以直接通过数的前半部分替换掉后半部分,得到结果:
12321
但你能保证这样得出的结果是最近的回文数吗?在12345的例子中似乎没什么问题,但看下面的例子:
12399
若是直接将其转为回文数,则结果为12321,但是回文数12421显然更接近12399。
所以我们应该考虑如下三种情况:
- 将整数直接转为回文数
- 求得小于该整数的回文数
- 求得大于该整数的回文数
得到这三个结果后,再进行差值的比较,然后取差值最小的那个回文数即可。
例如:99321,对于这个数:
- 首先求得情况一,直接转为回文数,则结果为
99399 - 其次求得情况二,求得小于它的回文数,结果为
99299 - 最后求得情况三,求得大于它的回文数,结果为
99499
最后计算差值,99299与99321的差值最小,即可得到最终结果。
接下来我们看看如何得到一个数的回文数,以99299为例,首先通过计算数字长度 / 2得到一个下标2,该位置即为数字的中心位置,以该位置为分割,左边部分的数字即为992,那么回文数的产生就是将左边部分的数字反转,得到299,再将其与左边部分数字拼接,得到99299,注意中心位置元素有重复,需要去掉,如下图所示:
可以用如下方法拼接回文数:
StringBuffer sb = new StringBuffer();
String prefix = String.valueOf(i);
sb.append(prefix);
StringBuffer rightNum = new StringBuffer(prefix).reverse();
// 处理奇偶长度
if (len % 2 == 0) {
sb.append(rightNum.substring(0));
} else {
sb.append(rightNum.substring(1));
}
String result = sb.toString();
还需要考虑特殊情况,当数为100时,拼接的回文数结果为9,而对于数字998,拼接后的结果为100001。
最后代码如下:
public static String nearestPalindromic(String n) {
long nu = Long.parseLong(n);
long ans = Integer.MAX_VALUE;
long result = 0;
// 得到所有情况的回文数
List<Long> list = getHuiWenShu(n);
// 遍历得到差值最小的
for (long num : list) {
long cha = Math.abs(num - nu);
if(cha < ans){
// 若回文数为本身,不处理
if(num != nu){
result = num;
ans = cha;
}
}
}
return Long.toString(result);
}
public static List<Long> getHuiWenShu(String n) {
int len = n.length();
// 构造特殊情况回文数
List<Long> list = new ArrayList<>();
list.add((long) Math.pow(10, len - 1) - 1);
list.add((long) Math.pow(10, len) + 1);
// 获取中心位置左边部分的数字
long leftNum = Long.parseLong(n.substring(0, (len + 1) / 2));
// 求得小于、本身、大于 n 的回文数
for (long i = leftNum - 1; i <= leftNum + 1; i++) {
StringBuffer sb = new StringBuffer();
String prefix = String.valueOf(i);
sb.append(prefix);
StringBuffer rightNum = new StringBuffer(prefix).reverse();
// 处理奇偶长度
if (len % 2 == 0) {
sb.append(rightNum.substring(0));
} else {
sb.append(rightNum.substring(1));
}
String result = sb.toString();
// 保存结果
list.add(Long.parseLong(result));
}
return list;
}
此题得解。