python算法4.28——LeetCode_886_PrimePalindrome

Question:

Find the smallest prime palindrome greater than or equal to N.

Recall that a number is prime if it's only divisors are 1 and itself, and it is greater than 1. 

For example, 2,3,5,7,11 and 13 are primes.

Recall that a number is a palindrome if it reads the same from left to right as it does from right to left. 

For example, 12321 is a palindrome.

  • 1 <= N <= 10^8
  • The answer is guaranteed to exist and be less than 2 * 10^8.

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

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

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

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

例如,12321 是回文数。

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

分析1:求最小回文数与最小素数的结合,使用回文数判断和素数判断即可

class Solution:
    def primePalindrome(self, N: int) -> int:
        isPrime = False
        isPalindrome = False
        if N<2:
            N = 2
        while True:
            isPrime = False
            isPrime = self.JudgePrime(N)
            if isPrime:
                isPalindrome = self.JudgePal(N)
                if isPalindrome:
                    return N
            N += 1

    def JudgePrime(self,n):
        for i in range(2,int(math.sqrt(n))+1):
            if n % i == 0:
                return False
        return True

    def JudgePal(self,n):
        str1 = str(n)
        str2 = ''.join(reversed(str1))
        if str1 == str2:
            return True
        return False

问题1:对数字依次进行遍历判断,耗费时间,超时示例:9989900

分析2:借鉴评论中的提示,根据如下数学规律进行优化

除 11 外的偶数位回文数,都能被 11 整除
能被 11 整数的数字特点:偶数位数字之和 = 奇数位数字之和。偶数位的回文数,偶数位的和一定等于奇数位的和,所以除了 11 其余的都不是素数。
除2外的偶数都不是素数

问题:先进行素数判断仍然耗费大量时间,超时示例:85709140

解决:将回文数判断置前以减少判断时间

class Solution:
    def primePalindrome(self, N: int) -> int:
        if N < 3:
            return 2
        elif N % 2 == 0:
            N += 1
        while self.JudgePal(N) == False or self.JudgePrime(N) == False:
            if N > 11 and len(str(N)) % 2 == 0:
                N = int(math.pow(10, len(str(N))) + 1)
            else:
                N += 2
        return N

    def JudgePrime(self, n):
        for i in range(2, int(math.sqrt(n)) + 1):
            if n % i == 0:
                return False
        return True

    def JudgePal(self, n):
        string = str(n)
        if string == string[::-1]:
            return True
        return False

分析3:利用数学规律:除2、3外,素数都在6左右两侧(必为6x+1或6x-1)。相较于用偶数进行过滤,可以进一步缩小范围。

问题,n1、n2大小不一定按顺序,可能造成过多判断甚至误判,错误示例:6,输出5

解决:对n1、n2赋值后排序

class Solution:
    def primePalindrome(self, N: int) -> int:
        if N < 3:
            return 2
        elif N == 3:
            return 3
        if self.JudgePal(N) == False or self.JudgePrime(N) == False:
            if 0 < N % 6 < 5:
                n1 = N - N % 6 + 5
                n2 = N - N % 6 + 7
            elif N % 6 == 0:
                n1 = N + 5
                n2 = N + 1
            elif N % 6 == 5:
                n1 = N + 6
                n2 = N + 2
        else:
            return N
        if n1>n2:
            n1,n2 = n2,n1
        while True:
            if self.Judge(n1) == False:
                if n1 > 11 and len(str(n1)) % 2 == 0:
                    n1 = int(10 ** len(str(n2))) + 1
                else:
                    n1 += 6
            else:
                return n1
            if self.Judge(n2) == False:
                if n2 > 11 and len(str(n2)) % 2 == 0:
                    n2 = int(10 ** len(str(n2))) + 1
                else:
                    n2 += 6
            else:
                return n2


    def Judge(self, n):
        if self.JudgePal(n) == False or self.JudgePrime(n) == False:
            return False
        return True

    def JudgePrime(self, n):
        for i in range(2, int(n ** 0.5) + 1):
            if n % i == 0:
                return False
        return True

    def JudgePal(self, n):
        string = str(n)
        if string == string[::-1]:
            return True
        return False

猜你喜欢

转载自blog.csdn.net/nominior/article/details/89637210
今日推荐