Let's say a positive integer is a superpalindrome if it is a palindrome, and it is also the square of a palindrome.html
Now, given two positive integers L
and R
(represented as strings), return the number of superpalindromes in the inclusive range [L, R]
.git
Example 1:github
Input: L = "4", R = "1000" Output: 4 Explanation: 4, 9, 121, and 484 are superpalindromes. Note that 676 is not a superpalindrome: 26 * 26 = 676, but 26 is not a palindrome.
Note:函數
1 <= len(L) <= 18
1 <= len(R) <= 18
L
and R
are strings representing integers in the range [1, 10^18)
.int(L) <= int(R)
這道題對於正整數定義了一種超級迴文數,即其自己是迴文數,而且是另外一個迴文數的平方,如今給了咱們一個範圍 [L, R],讓返回這個範圍內全部超級迴文數的個數。固然最暴力的辦法就是遍歷每一個數字,而後看其是不是迴文數字,而後再檢測其平方數是不是迴文數,這種方法基本不太可能經過 OJ,由於絕大多的數字都不是迴文數,每一個都檢測一遍實在是太費時間了,那麼應該怎麼辦呢?實際上咱們應該主動的去構建迴文數,對於一個迴文數字,若在兩邊各加上一個相同的數字,則新組成的數字必定也是迴文數字,那麼對於這個新組成的迴文數,只須要驗證一下其平方數是否也是迴文數便可,這樣就大大的減小了運算步驟,從而逃脫 OJ 的魔爪。ui
具體來講,因爲給定的L和R範圍超過了整型最大值,因此要轉爲長整型。而後須要使用上面提到的方法來構建迴文數,因爲迴文數有奇數和偶數兩種形式,好比 22 就是偶數形式,131 就是奇數形式。先構造偶數個的迴文數,就是直接在空串的兩端加相同的數字便可,構建的過程放到一個遞歸函數中。同理,構造奇數個的迴文數,就是先生成中間的單獨數字,這裏能夠是從0到9的任意數字,而後再在兩邊加相同的數字,調用遞歸函數。在遞歸函數,首先判斷當前數字的長度,若超過了9,說明當前數字的平方數長度會超過 18,須要直接返回,由於題目中限定了L和R的長度不超過 18。再判斷若當前數字不爲空,且第一個數字不爲0時,要驗證其平方數是否爲迴文數。由於多位數的首位不能是0,題目中給定了L和R的範圍是從1開始的,因此不會是單獨的0。此時咱們將當前數字的字符串轉爲長整型,而後計算其平方數,若該數字大於右邊界 right,則直接返回,不然看若數字大於等於左邊界,且是迴文數的話,結果 res 自增1。以後就要繼續構建新的迴文數,作法仍是在兩邊同時增長兩個相同的數字,並對每一個新構建的迴文數調用遞歸便可,參見代碼以下:code
class Solution { public: int superpalindromesInRange(string L, string R) { int res = 0; long left = stol(L), right = stol(R); helper("", left, right, res); for (char c = '0'; c <= '9'; ++c) { helper(string(1, c), left, right, res); } return res; } void helper(string cur, long& left, long& right, int& res) { if (cur.size() > 9) return; if (!cur.empty() && cur[0] != '0') { long num = stol(cur); num *= num; if (num > right) return; if (num >= left && isPalindrome(to_string(num))) ++res; } for (char c = '0'; c <= '9'; ++c) { helper(string(1, c) + cur + string(1, c), left, right, res); } } bool isPalindrome(string str) { int left = 0, right = (int)str.size() - 1; while (left < right) { if (str[left++] != str[right--]) return false; } return true; } };
Github 同步地址:htm
https://github.com/grandyang/leetcode/issues/906blog
參考資料:遞歸
https://leetcode.com/problems/super-palindromes/ci
https://leetcode.com/problems/super-palindromes/discuss/170774/Java-building-the-next-palindrome