Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
每日刷题第74天 2021.03.27
5253. 找到指定长度的回文数
- leetcode原题链接:leetcode-cn.com/contest/wee…
- 难度:中等
- 方法:思维题
题目描述
- 给你一个整数数组
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位数:9
- 2位数:9
- 3位数:90
- 4位数:90
- 5位数:900
- 6位数:900
- 例如:当前需要找的是长度为5的回文数。根据题意可知,每个第
K个回文数,可能会有不存在的情况,需要返回-1。 - 那么就需要寻找当前长度的回文数的上限(即:最大值)
- 接着分析:对于每一个长度内的回文数,都会有一个基本数(即:最小回文数,因为不包含
0,因此1开头)- 针对回文数,其从中间拆开,前面翻转后就是后面的数值,因此只需要处理前面的部分即可
- 举例:长度为5内的回文数,基本数是
10001,我们发现前半部分和后半部分相同,因此讨论一半100即可
- 第
K个元素就是基本数 +K - 1,为什么要减去1呢,因此基本数本身就是一个回文数- 因此
第k个回文数前半部分 = base + (K - 1) - 再根据奇偶性判断:(偶数)前半部分直接翻转过来拼接;(奇数)前半部分 + 前半部分去掉最后一位翻转
- 因此
具体的代码做法
- 几个字符串的函数
substr(start, len)从start下标开始,截取长度为len的字符串substring(start, end)从start下标开始,截取到end的字符串,但是不包含end下标
AC代码
var kthPalindrome = function(queries, intLength) {
let n = intLength,cap = 0, base = 0,ans = [];
let aver = parseInt(n / 2),isOdd = false;
if(n % 2 == 0){
cap = Math.pow(10, aver - 1) * 9;
base = Math.pow(10, aver - 1);
}else {
cap = Math.pow(10, aver) * 9;
base = Math.pow(10, aver);
isOdd = true;
}
// console.log(cap,isOdd)
let q = queries, len = q.length;
for(let i = 0; i < len; i++) {
if(q[i] > cap){
ans.push(-1);
}else {
let res = '';
let mm = base + (q[i] - 1) + '',lenM = mm.length;
// console.log(lenM)
if(isOdd){
// console.log('subStr',mm.substring(0, lenM - 1))
mm = mm + mm.substring(0, lenM - 1).split('').reverse().join('')
}else {
mm = mm + mm.split('').reverse().join('')
}
ans.push(mm);
}
}
return ans;
};
总结
- 第k个回文数,需要先找到基数,然后在计算其为第几个,往上加即可。
- 三个关键点:
- 找上限
- 找基本数
- 找第
k个数的方式