[LeetCode] 906. Super Palindromes 超級迴文數



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. 1 <= len(L) <= 18
  2. 1 <= len(R) <= 18
  3. L and R are strings representing integers in the range [1, 10^18).
  4. 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

https://leetcode.com/problems/super-palindromes/discuss/171467/c%2B%2B-straightforward-backtracking-solution

https://leetcode.com/problems/super-palindromes/discuss/170779/Java-Concise-DFS-Solution-with-Explaination-No-Cheating



LeetCode All in One 題目講解彙總(持續更新中...)

相關文章
相關標籤/搜索