本人算法萌新,为秋招找工作开始磨炼算法,算法题均用python实现,如果我有哪些地方做的有问题的,还请大家不吝赐教.
1.题干
给你一个字符串
s
,找到s
中最长的回文子串。示例 1:
输入:s = "babad" 输出:"bab" 解释:"aba" 同样是符合题意的答案。示例 2:
输入:s = "cbbd" 输出:"bb"提示:
1 <= s.length <= 1000
s
仅由数字和英文字母组成
2.思考
先想到双指针,对于回文串,首先要做到左右两端相等,然后不断往内收,直到两个指针重合或者错开,所以第一重循环遍历左指针,第二重循环寻找从右边往左走第一个与左指针值相等的值,然后开始上述过程,然后发现时间复杂度似乎有点过高了,所以进行了一些剪枝处理,之后又想到遍历长度,从最大长度开始遍历,随着寻找到的最长回文串不断更新最小长度的限制,直到寻找到答案,感觉也有些复杂,之后看了题解的动态规划算法,如果一个子串是回文串,那么当其去掉首尾两个字符之后,其仍然是一个回文串,所以用dp[i][j]来代表区间[i,j]是一个回文串,当i-1的值与j+1的值相等的时候,其状态转义也是一个回文串,其他的都不是回文串
3.代码
三重循环代码 QAQ
class Solution:
def longestPalindrome(self, s: str) -> str:
n, ans, left, right = len(s), 0, 0, 0
for l in range(n):
r = n - 1
while r >= l:
if s[r] == s[l]:
is_ok = True
length = r - l
start, end = l, r
if length < ans:
break
while start <= end:
if s[start] != s[end]:
is_ok = False
break
start += 1
end -= 1
if ans < length and is_ok:
ans = length
left = l
right = r
break
r -= 1
return s[left: right + 1]
if __name__ == "__main__":
solution = Solution()
s = "babad"
print(solution.longestPalindrome(s))
动态规划OVO
class Solution:
def longestPalindrome(self, s: str) -> str:
n = len(s)
dp = [[False] * n for _ in range(n)]
result = 0
start = 0
for i in range(n - 1, -1, -1):
for j in range(i, n):
# 当两个字符相等,并且(j-i <= 1)或者dp[i+1][j-1]为True时
if s[i] == s[j] and (j - i <= 1 or dp[i + 1][j - 1]):
dp[i][j] = True
if j - i >= result:
result = j - i + 1
start = i
return s[start:start + result]
if __name__ == "__main__":
solution = Solution()
s = "babad"
print(solution.longestPalindrome(s))
4.总结
这道题一开始没有想到回文串与其子串的关系,没有往动态规划那方面想,只想出了暴力解法.