寻找最近的回文数
难度:
标签:
题目描述
代码结果
运行时间: 25 ms, 内存: 15.9 MB
/*
* 思路:
* 1. 使用Java Stream API简化生成候选回文数的过程。
* 2. 通过map和filter生成候选列表。
* 3. 使用min找到最接近原始数字的回文数。
*/
import java.util.stream.Stream;
public class Solution {
public String nearestPalindromic(String n) {
long originalNum = Long.parseLong(n);
long len = n.length();
long prefix = Long.parseLong(n.substring(0, (int) (len + 1) / 2));
// 生成候选回文数并找到最接近的那个
return Stream.of(prefix, prefix + 1, prefix - 1)
.map(p -> createPalindrome(p, len % 2 == 0))
.filter(candidate -> candidate != originalNum)
.min((a, b) -> {
long diffA = Math.abs(a - originalNum);
long diffB = Math.abs(b - originalNum);
if (diffA != diffB) return Long.compare(diffA, diffB);
return Long.compare(a, b);
})
.get().toString();
}
private long createPalindrome(long prefix, boolean evenLength) {
String prefixStr = String.valueOf(prefix);
String reverse = new StringBuilder(prefixStr).reverse().toString();
return Long.parseLong(prefixStr + (evenLength ? reverse : reverse.substring(1)));
}
}
解释
方法:
题解思路主要分为几个步骤:1. 特殊情况处理:如果n小于10或者n等于10的幂次方,则直接返回n-1;如果n减1等于10的幂次方,则返回n-2;如果n加1等于10的下一个幂次方,则返回n+2。这些特殊情况处理主要是为了应对边界情况。2. 对于一般情况,先找到n的前半部分(对于奇数长度的n,中间的数字也包括在前半部分),然后构造三个候选的回文数,分别是将前半部分减1、不变、加1后,再将其翻转拼接到后半部分。3. 在这三个候选回文数中,找出与n差的绝对值最小的那个,如果有多个差值相同的,则返回较小的那个。
时间复杂度:
O(length)
空间复杂度:
O(length)
代码细节讲解
🦆
请问在处理特殊情况时,为什么对于小于10或等于10的幂次方的n,返回n-1就是最近的回文数?
▷🦆
在构造回文数时,为何选择将前半部分的数字分别减1、不变、加1?这样的操作对找到最近回文数有何作用?
▷🦆
如何处理奇数长度和偶数长度的n在构造回文数时的差异?具体是如何确定中间的数字是否应该包含在前半部分?
▷🦆
题解中提到使用min函数进行排序和选择最小值,能否详细解释min函数中的lambda表达式如何确保既考虑了差值最小又考虑了数值大小?
▷