[LeetCode][python3]0005. Longest Palindromic Substring

Start the Journey
N2I -2020.03.15

1. My first try


  1. class Solution:
  2. def longestPalindrome(self, s: str) -> str:
  3. if not s:
  4. return ""
  5. elif len(s)==1:
  6. return s
  7. l=1
  8. r=-1
  9. max_sub=0
  10. for i in range(1,len(s)):
  11. cur_l,cur_r=self.lgcheck(s,i)
  12. if r-l-1<cur_r-cur_l-1:
  13. l=cur_l
  14. r=cur_r
  15. return s[l+1:r]
  16. def lgcheck(self,s,start):
  17. start_l=start-1
  18. start_r=start+1
  19. while start_l>=0 and start_r<len(s):
  20. if s[start_l]!=s[start_r]:
  21. break
  22. else:
  23. start_l-=1
  24. start_r+=1
  25. cur_max=start_r-start_l-1
  26. r=start_r
  27. l=start_l
  28. start_r=start
  29. start_l=start-1
  30. while start_l>=0 and start_r<len(s):
  31. if s[start_l]!=s[start_r]:
  32. break
  33. else:
  34. start_l-=1
  35. start_r+=1
  36. if cur_max<start_r-start_l-1:
  37. r=start_r
  38. l=start_l
  39.  

Explanation:

Just a normal solution for beginner.

2. A better solution


  1. class Solution:
  2. def longestPalindrome(self, s: str) -> str:
  3. str_len = len(s)
  4. # if length of string < 2 or s is palindrome already
  5. if str_len < 2 or s == s[::-1]:
  6. return s
  7. start, max_len = 0, 1
  8. for i in range(1, str_len):
  9. odd_start = i - max_len - 1
  10. even_start = i - max_len
  11. odd = s[odd_start:i + 1] # len(odd) = max_len + 2
  12. even = s[even_start:i + 1] # len(even) = max_len + 1
  13. if odd_start >= 0 and odd == odd[::-1]:
  14. start = odd_start
  15. max_len += 2
  16. elif even_start >= 0 and even == even[::-1]:
  17. start = even_start
  18. max_len += 1
  19. return s[start:start + max_len]
  20.  

Note:

  • even[::-1] is the reverse array for even[:].
  • s[a::b] is a sub_array of s, a stands for the start index (default 0 or -1 when b<0), b stands for what length for a jump.
  1. print("note for s[a::b]")
  2. print("while a stants and b>0")
  3. s=[0,1,2,3,4,5]
  4. s[::1]
  5. >>>[0,1,2,3,4,5]
  6. s[1::]
  7. >>>[1,2,3,4,5]
  8. s[1::2]
  9. >>>[1,3,5]
  10. s[1::3]
  11. >>>[1,4]
  12. s[2::2]
  13. >>>[2,4]
  14. print("while a <len(s) and b<0")
  15. s[::-1]
  16. >>>[5,4,3,2,1,0]
  17. s[::-2]
  18. >>>[5,3,1]
  19. s[-2::-2]
  20. >>>[4,2,0]

Explanation:

This solution use even==even[::-1] to check the selecting area even=s[even_start,i+1]is palindrome or not. Since even or odd will always be 1 or 2 size longer then the current longest substring. start stands for the start of the current longest substring, will only changes when it finds a new longest one in odd or even.