題目連結:
題目意譯:
讓我們叫一正整數為一個超級迴文如果該數是一個迴文,且該數是一個迴文的平方。
給定兩個正整數 left 、 right 以字串表示,回傳 [left, right] 範圍中(含 left 和 right 自身)有多少個超級迴文數。
限制:
1 ≦ left.length 、 right.length ≦ 18
left 和 right 只會由數字組成。
left 和 right 沒有任何前導 0。
left 和 right 代表著範圍 [1, 10 ^ 18] 中的整數。
left 小於等於 right。
範例測資:
範例 1:
輸入: left = "4", right = "1000"
輸出: 4
解釋: 4 、 9 、 121 和 484 為超級迴文。
注意, 676 不是一個超級迴文: 26 × 26 = 676 ,但是 26 並不是一個迴文。
範例 2:
輸入: left = "1", right = "2"
輸出: 1
解題思維:
超級迴文因為要是某個迴文的平方,所以當有一個數字 N 的某位數是 3 以上(含)的數字時, N ^ 2 絕對不是一個迴文(除非 N = 3)。
例如 131 ^ 2 = 17161 、 52125 ^ 2 = 2717015625 、 1003001 ^ 2 = 1006011006001 等等。而原因是平方時,那些 ≧ 3 的位數會在平方的過程中自乘,再加上有其他位數的影響(如果沒其他位數,3 ^ 2 是一個迴文數,所以 N = 3 會是一個特例)因此會使得結果進位。
因此超級迴文的平方根 N 的數字只會有 0 、 1 、 2 出現。
因此我們可以窮舉出以下數字(「_」可以各自填入 0 、 1 或是 2 ):
11
22
1_1
2_2
1__1
2__2
1___1
2___2
1____1
2____2
1_____1
2_____2
1______1
2______2
1_______1
2_______2
然後先判斷這些數字是不是迴文(實際上,窮舉的時候可以直接窮舉出迴文,只要在左半側填入一個數字其右半側對應的位置也填相同數字便可以確保是迴文)。
接著將這些數字平方看看平方後是否也是迴文。如果是,我們就找到了一個超級迴文。
因此我們可以將這些超級迴文存進一個陣列(上述過程忽略了 1 、 4 、 9 這三個數字,記得加進陣列裡)裡(LeetCode 的建表方式參見
這題),然後看哪些數字介於 [left, right] 之間即可得到所求。
而如果定義上界為 B (在本題為 10 ^ 18),則上述的方法為 O(3 ^ (log (B ^ (1 ÷ 4))))。
此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。