【问题标题】:Longest Palindromic Subsequence最长回文子序列
【发布时间】:2018-04-11 13:10:33
【问题描述】:

我尝试使用递归来解决它。这是我的代码。 “ABDA”失败(返回 3 而不是 1)。这样做的原因对我来说很清楚,但我不知道如何解决这个问题。

def lps(s):
    print(s)
    n = len(s)
    if n <= 1:
        return n

    if s[0] == s[n-1]:
        return 2 + lps(s[1:-1])
    return max(lps(s[:-1]), lps(s[1:]))

【问题讨论】:

  • 您能否提供一些更复杂的预期输出示例?我虽然你在寻找最长的前缀也是一个还原的前缀,但根据 MBo 的解释,你不是。你真的是在谈论找到最长的回文子序列(例如“acbabac”中的“ababa”、“cbabc”或“cabac”),最长的回文因子/子字符串(例如“acbabac”中的“bab”),还是我最初的解释正确吗?
  • 请说明您的意思是回文子串(连续)还是子序列(在您的示例中为adaaba
  • 3 是根据standard meaning of the word subsequence 的正确答案。如果你需要别的东西,你最好用不同的词来命名它(例如子字符串)。

标签: python algorithm computer-science


【解决方案1】:

该问题错过了一些信息,无法准确了解您要查找的内容。我将在下面假设您想​​要找到也是后缀的最长前缀(以相反的顺序)。

递归的想法是比较第一个和最后一个字符。如果它们不相等,则它不能是回文(在这种情况下,返回 0)。如果它们相等,则“回文部分”的长度为 1 + 剩余单词的“回文部分”的长度(即没有首尾字符的单词):

def lps(word):
  if len(word) > 0 and word[0] == word[-1]:
    return 1 + lps(word[1:-1])
  else:
    return 0

print(lps('abc'))
print(lps('abca'))
print(lps('abba'))
print(lps('abcba'))
print(lps('abda'))

结果为@​​987654322@。

这些数字代表最长的前缀(以相反的顺序)也是一个后缀。

如您所见,“abba”导致长度为 2(因为“ab”),即使它是长度为 4 的回文。如果您想获得该回文的总长度,可能更容易迭代地做:

def lps_full(word):
  i = len(word)
  while i > 0:
    if word[:i] == word[:-i-1:-1]:
      return i
    i -= 1
  return 0

同样的例子导致0, 1, 4, 5, 1,即,对于不是回文的单词,与上面相同的结果,对于单词的长度是相同的。

如果您必须使用相同的函数,则可以递归定义:

def lps(word, i=0):
  if len(word) > i and word[i] == word[-i-1]:
    return lps(word, i+1)
  else:
    return i

【讨论】:

  • 打印(lps('abac'))
  • 看来你的意思是别的。我希望 3 (aba)
  • 好的,我明白了:)我会用另一个函数更新我的答案,然后;)
  • (否则我不会:-D)找到最长的回文子序列(甚至最长的回文因子)涉及更多,而且难度可能更多地与算法有关而不是其实现。
猜你喜欢
  • 2017-02-25
  • 2012-09-07
  • 2012-08-29
  • 2019-06-18
  • 1970-01-01
  • 2022-07-21
  • 2011-06-15
  • 2018-05-13
  • 1970-01-01
相关资源
最近更新 更多