最近写题目的时候接触到了一些有关于回文数的题目,才发现构造回文数的过程很有意思
1. 枚举回文数
1.1 背景
在leetcode上面写题目的时候遇见一个需要枚举某个范围内所有回文数的题目:等数数组,这个题目在看题解的时候,返现了构造回文数的思路和技巧
这个题目需要将10^9内的所有回文数枚举并存储起来备用,所有才接触到了回文数的构造
1.2实现思路
我们构造回文数的时候,需要借助翻转的思想,将高位沿着对称对称轴翻转到低位,这样就可以获得一个回文数了。但是需要注意,翻转的时候可能会对应奇数长度和偶数长度的回文数,比如10,翻转过去对应了101和1001,这两个回文数的都是以10为高位的回文数。
1.3 代码实现
下面的代码实现了穷举10^9内的所有回文数
# 严格按顺序从小到大生成所有回文数(在10^9以内)
pal = []
base = 1
while base <= 10000:
# 生成奇数长度回文数
for i in range(base, base * 10):
x = i
t = i // 10
while t:
x = x * 10 + t % 10
t //= 10
pal.append(x)
# 生成偶数长度回文数
if base <= 1000:
for i in range(base, base * 10):
x = t = i
while t:
x = x * 10 + t % 10
t //= 10
pal.append(x)
base *= 10
2.寻找最近的回文数
2.1 题目描述
这个是leetcode上面一个与回文数相关的题目,也是利用到了上面构造回文数的思想
2.2题解思路
题目的题解思路来自leetcode的官方题解:
2.3实现代码
下面是Java的实现方法(其他语言的题解可以打开上面的连接查看)
class Solution {
public String nearestPalindromic(String n) {
long selfNumber = Long.parseLong(n), ans = -1;
List<Long> candidates = getCandidates(n);
for(long candidate : candidates){
if(candidate != selfNumber){
if(ans == -1||
Math.abs(candidate - selfNumber) < Math.abs(ans - selfNumber)||
Math.abs(candidate - selfNumber) == Math.abs(ans - selfNumber) && candidate < ans){
ans = candidate;
}
}
}
return Long.toString(ans);
}
public List<Long> getCandidates(String n){
int len = n.length();
List<Long> candidates = new ArrayList<Long>(){{
add((long)Math.pow(10, len -1) - 1);
add((long)Math.pow(10, len) + 1);
}};
long selfPrefix = Long.parseLong(n.substring(0, (len + 1) / 2));
for(long i = selfPrefix - 1; i <= selfPrefix + 1; i++){
StringBuffer sb = new StringBuffer();
String prefix = String.valueOf(i);
sb.append(prefix);
StringBuffer suffix = new StringBuffer(prefix).reverse();
sb.append(suffix.substring(len & 1));
String candidate = sb.toString();
try{
candidates.add(Long.parseLong(candidate));
}catch(NumberFormatException ex){
continue;
}
}
return candidates;
}
}