import math classSolution: defsuperpalindromesInRange(self, L: str, R: str) -> int: count = 0 for i in range(int(L), int(R) + 1): if str(i)[::-1] == str(i): if int(math.sqrt(i))**2 == i: if str(int(math.sqrt(i))) == str(int(math.sqrt(i)))[::-1]: count += 1 return count
第二层:优化循环
为什么要使得i从L遍历到R呢?如果我们从根号L遍历到根号R,不是就省了很多遍历次数了吗?说干就干!
这是很不错的进步,然而很遗憾的是,这样子遍历完还是超时了。
1 2 3 4 5 6 7 8
import math classSolution: defsuperpalindromesInRange(self, L: str, R: str) -> int: count = 0 for i in range(int(math.sqrt(int(L))), int(math.sqrt(int(R))) + 1): if str(i)[::-1] == str(i) and str(i**2)[::-1] == str(i**2): count += 1 return count
第三层:优化回文数判断
会不会我们对回文数的处理太暴力了呢?如果按照第九题的判断回文数的方法,会不会省掉很多时间呢?
然而,还是超时了。
方法是,对回文数的后半部分进行反转,比较前半部分和后半部分是否相同
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
import math classSolution: defisPalindrome(self, x: int) -> bool: if x < 0or (x % 10 == 0and x != 0): returnFalse revertedNumber = 0 while x > revertedNumber: revertedNumber = revertedNumber * 10 + x % 10 x //= 10 return x == revertedNumber or x == revertedNumber//10 defsuperpalindromesInRange(self, L: str, R: str) -> int: count = 0 for i in range(int(math.sqrt(int(L))),int(math.sqrt(int(R)))+1): if self.isPalindrome(i) and self.isPalindrome(i**2): count += 1 return count
classSolution: # 判断是否是回文 defisPalindrome(self, x: int) -> bool: if x < 0or (x % 10 == 0and x != 0): returnFalse revertedNumber = 0 while x > revertedNumber: revertedNumber = revertedNumber * 10 + x % 10 x //= 10 return x == revertedNumber or x == revertedNumber // 10
# 给定上一个回文计算下一个回文 defnextPalindrome(self, x: int) -> int: if x == 1111111: return2000002 if x == 101111101: return110000011 if x == 110111011: return111000111 if x == 111010111: return111101111 if x == 111111111: return200000002 if x // 10 == 0: if x == 1: return2 elif x == 2: return3 else: return11 # 把数放到list里方便操作 list_x = [] tmp = x while tmp != 0: list_x.insert(0, tmp % 10) tmp //= 10
# 针对结尾是2的情况处理 if x % 10 == 2: if len(list_x) % 2 == 0: if (x - 2) // 2 == 10 ** (len(list_x) - 1): return10 ** len(list_x) + 1 else: if list_x[len(list_x) // 2] == 0: return x + 10 ** (len(list_x) // 2) else: return10 ** len(list_x) + 1
# 在字符串长度是奇数的情况下 if len(list_x) % 2 == 1: mid_index = len(list_x) // 2 if list_x[mid_index] != 2: list_x[mid_index] += 1 else: mid_index -= 1 while list_x[mid_index] != 0and mid_index > 0: mid_index -= 1 if mid_index == 0: return2 * 10 ** (len(list_x) - 1) + 2 else: for i in range(mid_index + 1, len(list_x) - mid_index - 1): list_x[i] = 0 list_x[mid_index] += 1 list_x[-mid_index - 1] += 1
# 把list转成int next_palindrome = 0 for i in list_x: next_palindrome = next_palindrome * 10 + i return next_palindrome
# 给定任意数,计算下一个比它大的回文 deffirstPalindrome(self, x): if x == 1: return1 length = len(str(x)) i = 10 ** (length - 1) + 1 while i < x: i = self.nextPalindrome(i) return i