Find the smallest prime palindrome greater than or equal to N
.html
Recall that a number is prime if it's only divisors are 1 and itself, and it is greater than 1. git
For example, 2,3,5,7,11 and 13 are primes.github
Recall that a number is a palindrome if it reads the same from left to right as it does from right to left. less
For example, 12321 is a palindrome.函數
Example 1:優化
Input: 6 Output: 7
Example 2:code
Input: 8 Output: 11
Example 3:htm
Input: 13 Output: 101
Note:blog
1 <= N <= 10^8
2 * 10^8
.
這道題給了咱們一個整數N,讓找一個大於等於N的迴文質數,既要求是質數,又要求是迴文數。其實這道題能夠看成兩道題揉到了一塊兒,判斷質數和迴文數分別能夠看成單獨的題。沒想太多,博主上來就準備暴力搜索,先寫兩個子函數,分別用來判斷質數和迴文數,而後就直接從N開始搜索了,對每一個數字都分別調用判斷質數和迴文數的子函數,若都知足,則返回該數便可。理想是豐滿的,現實是骨感的,OJ 教你作人系列之 TLE 超時!想着優化一下吧,直接跳過全部的偶數吧(2除外),仍是跪。看來小優化是行不通,得大改。leetcode
問題出如今哪裏了呢?確定是判斷質數和迴文數的子函數太佔時間了,怎麼優化呢?對於質數來講,很是的不規則,沒有太好的辦法來直接組成質數,而是須要經過驗證來看其是否爲質數。而回文數就不同的,很是的有特色,咱們能夠直接按規律來組成迴文數,而不是對每一個數字都進行驗證,這樣的話就至關於去掉了驗證迴文數的步驟,是一個至關大的提高。怎麼拼接呢?因爲給了N的取值範圍,咱們能夠遍歷前一半的全部數字,而後翻轉一下,組成後一半,兩個拼起來就是迴文數了。但問題又來了,迴文數的長度是分奇偶的,長度爲奇數的迴文數,最中間的數字是沒有對應的,腫麼辦?其實這道題挺考數學知識的,用到了一個比較偏門的定理,就是全部長度爲偶數的迴文數字必定是 11 的倍數。博主表示從沒聽過這個定理,證實過程請參見 lee215 大神的帖子。經過這個定理,能夠知道除了11以外,全部長度爲偶數的迴文數都不是質數,那麼當N爲 [8, 11] 中的數字時,纔會返回11,這個就當 corner cases 提早判斷了,對於其餘全部的都是符合規律的。那就能夠只組奇數的迴文數了,因爲N的範圍是 [1, 1e8],因此前一半範圍是 [1, 1e5),由於還包含了最中間的那個數字,因此在翻轉以後,記得要把第一位數字去掉,由於最中間的數字只能保留一個,而後把兩個數字拼接起來。此時再判斷這個拼接後的數字是否大於等N,而且是不是質數,都知足的話返回這個數字便可,參見代碼以下:
class Solution { public: int primePalindrome(int N) { if (N >= 8 && N <= 11) return 11; for (int i = 1; i < 1e5; ++i) { string s = to_string(i), t(s.rbegin(), s.rend()); int x = stoi(s + t.substr(1)); if (x >= N && isPrime(x)) return x; } return -1; } bool isPrime(int num) { if (num < 2 || num % 2 == 0) return num == 2; int limit = sqrt(num); for (int i = 3; i <= limit; ++i) { if (num % i == 0) return false; } return true; } };
Github 同步地址:
https://github.com/grandyang/leetcode/issues/866
相似題目:
參考資料:
https://leetcode.com/problems/prime-palindrome/
https://leetcode.com/problems/prime-palindrome/discuss/146798/Search-Palindrome-with-Odd-Digits