5253. 找到指定长度的回文数(思维题)

266 阅读3分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

每日刷题第74天 2021.03.27

5253. 找到指定长度的回文数

题目描述

  • 给你一个整数数组 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个数的方式