LeetCode探索(126):866-回文素数

137 阅读1分钟

LeetCode探索(126):866-回文素数

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第23天,点击查看活动详情 >>

题目

求出大于或等于 N 的最小回文素数。

回顾一下,如果一个数大于 1,且其因数只有 1 和它自身,那么这个数是素数

例如,2,3,5,7,11 以及 13 是素数。

回顾一下,如果一个数从左往右读与从右往左读是一样的,那么这个数是回文数。

例如,12321 是回文数。

示例 1:

输入:6
输出:7

示例 2:

输入:8
输出:11

示例 3:

输入:13
输出:101

提示:

  • 1 <= N <= 10^8
  • 答案肯定存在,且小于 2 * 10^8

思考

本题难度中等。

首先是读懂题意。我们需要求出大于或等于 n 的最小回文素数。我们可以先写出判断素数的方法和判断回文字符串的方法。

判断数字 n 是否为素数,我们可以从2开始遍历,直至数字 n - 1,判断是否存在数字能整除 n。若存在,则不是素数,否则是素数。我们可以进一步优化,只判断 [2, n^0.5] 范围内即可。

判断回文字符串,我们可以反转给出数字,判断最终的新数字是否与原数字相等。也就是不断取出数字 n 的个数位的数字,然后加到新数字上去,每次相加时要注意移位。

最小回文素数,需要同时满足回文数字和素数两个条件。考虑到任何偶数长度的回文数都可被11整除,这里跳过范围 [Math.pow(10, 7), Math.pow(10, 8) - 1]

解答

方法一:数学

/**
 * @param {number} n
 * @return {number}
 */
function primePalindrome(n) {
  while (true) {
    if (n == reverse(n) && isPrime(n))
      return n
    n++
    // 任何偶数长度的回文数都可被11整除
    if (Math.pow(10, 7) < n && n < Math.pow(10, 8)) {
      n = Math.pow(10, 8)
    }
  }
}
function isPrime(n) {
  if (n < 2) return false
  let half = Math.floor(Math.sqrt(n))
  for (let d = 2; d <= half; ++d) {
    if (n % d == 0) return false
  }
  return true
}
function reverse(n) {
  let ans = 0
  while (n > 0) {
    ans = 10 * ans + (n % 10)
    n = Math.floor(n / 10)
  }
  return ans
}

复杂度分析:

  • 时间复杂度:O(n)。
  • 空间复杂度:O(1)。

参考