0
点赞
收藏
分享

微信扫一扫

力扣 最长回文子串 —— 有时dfs优于dp

钎探穗 2022-02-04 阅读 42

先给出dp的代码 (clock是我自己写的一个测时间的类)

class solution:
    def longestPalindrome(self, s: str) -> str:
        str_len = len(s)
        index = 0
        pace = 0

        dp = [[0 for _ in s] for _ in s]
        for idx in range(str_len):
            dp[idx][idx] = 1

        for idx in range(str_len - 1):
            if s[idx] == s[idx + 1]:
                dp[idx][idx + 1] = 1
                if pace < 1:
                    pace = 1
                    index = idx

        for p in range(2, str_len):
            for left in range(str_len):
                for right in range(left + p, str_len):
                    if s[left] == s[right]:
                        if dp[left + 1][right - 1]:
                            dp[left][right] = 1
                            if pace < p:
                                pace = p
                                index = left

        return s[index: index + pace + 1]

temp = solution()
print(*clock(temp.longestPalindrome, test).result)

dp的具体思路怎么样我就不讲了,毕竟在这个题里面表现很差,对于长度800 +的测评数据,dp用的时间大致在8.5 s以上,但是做好剪枝的dfs却只需要不到0.1 s的时间

dfs的代码框架如下。定义val函数判断是否为回文串,第二个for循环设置为 range(left + pace) 即只搜索比当前选择更优的状态

str_len = len(s)
index = 0
pace = 0
# pace: 步长指 right- left
for left in range(str_len):
    for right in range(left + pace + 1, str_len):
        if val(left, right):
            if right - left > pace:
                pace = right - left
                index = left
return s[index: index + pace + 1]

而val函数的编写如下,思路就是left和right两个指针往中间靠,边靠边校对字符是不是一样

def val(left, right):
    while left < right:
        if s[left] == s[right]:
            left += 1
            right -= 1
        else:
            return False
    return True

对于我这种只想参加蓝桥杯的菜鸟来说,能过就很不错了

举报

相关推荐

0 条评论