“Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。”
一、题目描述
给你一个整数数组 queries 和一个 正 整数 intLength ,请你返回一个数组 answer ,其中 answer[i] 是长度为 intLength 的 正回文数 中第 queries[i] 小的数字,如果不存在这样的回文数,则为 -1 。
回文数 指的是从前往后和从后往前读一模一样的数字。回文数不能有前导 0 。
示例 1:
输入:queries = [1,2,3,4,5,90], intLength = 3
输出:[101,111,121,131,141,999]
解释:
长度为 3 的最小回文数依次是:
101, 111, 121, 131, 141, 151, 161, 171, 181, 191, 201, ...
第 90 个长度为 3 的回文数是 999 。
示例 2:
输入:queries = [2,4,6], intLength = 4
输出:[1111,1331,1551]
解释:
长度为 4 的前 6 个回文数是:
1001, 1111, 1221, 1331, 1441 和 1551 。
提示:
1 <= queries.length <= 5 * 1041 <= queries[i] <= 1091 <= intLength <= 15
二、思路分析
解回文数的类型题,不能蛮干,关键在于智取,我们来举例子找规律:
例如 intLength 为 3 ,那么所有长度为 3 的回文数按顺序排为
- 101(1)
- 111(2)
- 121(3)
- 131(4)
- 141(5)
- ......
- 999(90)
可以发现,左右两边是相同的数字,中间的数字为括号里的数字减
1(括号里的数字为queries数组的元素),因此我们可以得出解题思路如下: - 定义一个位数为
(intLength + 1) / 2 - 1的最小数half,在此基础上+ queries[i] - 1,赋值为tmp,作为回文数的左半边。 - 现在要还原回文数的右半边,我们将
tmp转换为字符串,方便还原。还原过程为右边的字符一个个赋值为左边的字符,但由于奇偶性的问题,还需注意:为奇数的话中间的数是不用复制的。
三、AC 代码
/**
* @param {number[]} queries
* @param {number} intLength
* @return {number[]}
*/
var kthPalindrome = function(queries, intLength) {
let res = [];
const k = Math.floor((intLength + 1) / 2);
let half = 1;
for (let i = 0; i < k - 1; i++) {
half *= 10;
}
for (const x of queries) {
if (x > 9 * half) {
res.push(-1);
} else {
const tmp = half + x - 1;
const str = `${tmp}`;
let str2 = str;
const to = ((intLength % 2) === 1) ? str.length - 1 : str.length
for (let i = to - 1; i >= 0; i --) {
str2 += str[i];
}
res.push(+str2);
}
}
return res;
};