LeetCode 回文素数

版权声明:本文为博主原创文章,博客地址:https://blog.csdn.net/qq_41855420,未经博主允许不得转载。 https://blog.csdn.net/qq_41855420/article/details/91351016

求出大于或等于 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。

\color{blue}思路分析: 这道题可能有一部分的人上来就开始暴搜,然而测试数据量不大,蛋式数据非常大。这道题有几个需要注意点:

第一点:我们不能直接去穷举num,然后判断这个数是否素数、回文数,我们可以先从小到大构造回文数,然后去判断它是否是素数。(有人可能会问,能不能直接构造素数,再判断是否是回文数?这种思路理论上是可行的,蛋式从小到大构造素数会比从小到大构造回文数要难一些。)

第二点:对于偶数长度的回文数,都能被“11”整除。因此大于“11”的偶数长度的 回文数 只有“11”是质数。所以如果遇到“1001”这种,可以直接跳到“10001”开始,因为[1001, 9999]中的回文数都能被“11”整除。(这是一个数学定律,可以自行百度)

第三点:有第二点可知,我们构造的回文数都是奇数长度,比如“12321”,回文特性为关于中间数字对称,比如其中的"12"和“21”关于中间的’3’对称。那么回文构造的下一个数是什么?如果你此时想着直接把“12321” + 1,然后接着构造,那么这会消耗大量的时间。我们需要直接构造出下一个回文数“12421”,不难发现,增量tempVal = “100” = pow(10, len(“12421”) / 2)。

具体实现:

class Solution {
public:
    int primePalindrome(int N) {
        if (N < 12){
        //对于小于12的,可直接找出对应的结果
            for (int i = N; i < 100; ++i){
                if (isPrime(i)){
                    return i;
                }
            }
        }
        int tempVal = 1;//构造回文的增量
        for (int i = N; i < INT_MAX / 10; i += tempVal){
            string nStr = to_string(i);
            int strSize = nStr.size();//数字的长度
            //数字长度为偶数的回文数字都能被11整除,也就是说比如"1001",在“1001 - 9999”这些偶数长度的回文数字中没有质数
            if (strSize % 2 == 0){
                i = pow(10, strSize);//比如“1001”,直接跳到“10000”,也就是数字长度增大一位
                nStr = to_string(i);
            }
            tempVal = pow(10, strSize / 2);//重新计算增量,比如“12321”的下一个元素为“12421”,增量为“100”
            string rightStr = nStr.substr(0, strSize / 2);
            reverse(rightStr.begin(), rightStr.end());//将左半边对称反转为右半边
            //然后将left + 中间数字 + right合并
            i = stoi(nStr.substr(0, strSize / 2 + 1) + rightStr);
            if (i < N){
                continue;
            }
            //由于构造的i已经是回文,所以只要判断它是否是质数,并且比N大
            if (isPrime(i)){
                return i;
            }
        }
        return -1;
    }
    //判断num是否是质数
    bool isPrime(int num){
        if (num == 1){
            return false;
        }
        //查找[1, sqrt(num)]是否有因子
        for (int i = sqrt(num); i > 1; --i){
            if (num % i == 0){
                return false;
            }
        }
        return true;
    }
};

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_41855420/article/details/91351016
今日推荐