数学
类型第32篇解题报告
leetcode第866题:回文素数
https://leetcode-cn.com/problems/prime-palindrome
【题目】
求出大于或等于 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。
【思路】
回文数,简单,判断str(num)是否等于str(num)[::-1]
素数,简单,判断2到sqrt(num)是否能被num整除
回文素数,把两个合在一起就行了
但是,时间复杂度太高!
刷了两天,我也投降了,看了网上的解答,牛逼
主要使用了两个技巧
一是排除了除11外的所有偶数。想想,能被11整除的数有什么特点呢,奇数位数字之和 - 偶数位数字之和 等于11的倍数;偶数素数有什么特点呢,奇数位数字之和 = 偶数位数字之和。那么,除11外,偶数位数字,不存在回文素数。
二是只判断6x-1和6x+1的数。怎么来的呢?大于6的数,6x能被2整除,6x+2能被2整除,6x+3能被3整除,6x+4能被2整除,只有6x+1和6x-1可能素数。
【代码】
python版本
class Solution(object):
def primePalindrome(self, N):
"""
:type N: int
:rtype: int
"""
ls = [0, 2, 3, 5, 7, 11]
if N <= 11:
for i in range(1, 6):
if ls[i-1] < N <= ls[i]:
return ls[i]
# 能被11整除的数,奇数位之和-偶数位之和 能被 11 整除
# 偶数位数的素数,奇数位之和=偶数位之和
# 因此,偶数位数的数,不存在满足条件的值(除了11)
res = N - 1
while True:
if len(str(res)) % 2 == 0:
res = 10 ** len(str(res))
res += 1
# 回文数
if str(res) != str(res)[::-1]:
continue
# 除了2和3,素数都为6x-1或者6x+1
if res % 6 != 1 and res % 6 != 5:
continue
flag = True
for i in range(2, int(math.sqrt(res)) + 1):
if res % i == 0:
flag = False
break
if flag:
return res