1. 程式人生 > >【LeetCode】906. Super Palindromes 解題報告(Python)

【LeetCode】906. Super Palindromes 解題報告(Python)

作者: 負雪明燭
id: fuxuemingzhu
個人部落格: http://fuxuemingzhu.cn/


目錄

題目地址:https://leetcode.com/problems/super-palindromes/description/

題目描述

Let’s say a positive integer is a superpalindrome if it is a palindrome, and it is also the square of a palindrome.

Now, given two positive integers L and R (represented as strings), return the number of superpalindromes in the inclusive range [L, R].

Example 1:

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]雙閉區間內,所有的超級迴文數個數。超級迴文數是指本身是迴文數,並且它的算數平方根也是迴文數。

解題方法

BFS解法

暴力求解的話一定超時,很明顯超級迴文數是很稀少的,我們還是想想怎麼能找規律吧。這是一些超級迴文數:

# n, n^2
(1, 1)
(2, 4)
(3, 9)
(11, 121)
(22, 484)
(101, 10201)
(111, 12321)
(121, 14641)
(202, 40804)
(212, 44944)
(1001, 1002001)
(1111, 1234321)
(2002, 4008004)

可以注意到,在除了(1,4,9)之外的其他超級迴文數的算數平方根都是有0,1,2組成,而且兩頭都是由1或者2構成。

所以可以想到BFS的解法,我們使用一個佇列儲存的是迴文的算數平均數n,然後我們拿出佇列的每個元素,像中間部分插入0,1,2作為候選的n(保證仍然是迴文),然後把候選的n再次放入到佇列中去,如果算數平均數n的平方大於R了,就不用拿他計算新的數字了。

最後還需要把1,2,3給放入到候選裡面去,也要判斷候選的迴文算數平均數的平方是不是迴文數,如果是的話,結果加一。

時間複雜度不會算,空間複雜度不會算.超過65%.

class Solution:
    def superpalindromesInRange(self, L, R):
        """
        :type L: str
        :type R: str
        :rtype: int
        """
        que = collections.deque(["11", "22"])
        candi = set()
        while que:
            size = len(que)
            for _ in range(size):
                p = que.popleft()
                candi.add(p)
                if int(p) ** 2 > int(R):
                    continue
                for j in ["0", "1", "2"]:
                    q = (p[:len(p)//2] + j + p[len(p)//2:])
                    que.append(q)
        candi.add("1")
        candi.add("2")
        candi.add("3")
        res = 0
        for cand in candi:
            if int(L) <= int(cand) ** 2 <= int(R) and self.isPalindromes(int(cand) ** 2):
                res += 1
        return res
                
            
    def isPalindromes(self, s):
        s = str(s)
        N = len(s)
        for l in range(1, N // 2):
            if s[l] != s[N - 1 - l]:
                return False
        return True

相似題目

參考資料

https://leetcode.com/problems/super-palindromes/discuss/171450/Python-AC-bfs-detail-explanation

日期

2018 年 11 月 3 日 —— 霧霾的週六