返回

巧用动态规划和 DFS 解题,通关 LeetCode 131. Palindrome Partitioning!

后端

写在前面

嘿,各位热爱算法的伙伴们,欢迎来到 LeetCode 131 题:Palindrome Partitioning 的题解之旅!今天,我们将一起探索两种解决该问题的巧妙方法:动态规划和深度优先搜索 (DFS)。让我们用 Python 作为我们的编程伙伴,携手攻克这个难题吧!

题意解析

Palindrome Partitioning 问题是这样的:给你一个字符串 s,你需要将它分割成一些子字符串,使得每个子字符串都是回文串。回文串是指正读反读都一样的字符串,比如 "abba"、"racecar" 等等。

解法一:动态规划

首先,我们来看看动态规划的解法。动态规划是一种自底向上的算法,它将问题分解成更小的子问题,然后逐步求解,最终得到整个问题的解。在这个问题中,我们可以定义一个二维数组 dp[i][j],其中 dp[i][j] 表示字符串 s 从第 i 个字符到第 j 个字符的子字符串是否是回文串。

解法二:深度优先搜索

除了动态规划,我们还可以使用深度优先搜索 (DFS) 来解决这个问题。DFS 是一种自顶向下的算法,它从问题的根节点开始,依次访问每个子节点,直到找到一个解或者穷尽所有可能性。在这个问题中,我们可以从字符串 s 的第一个字符开始,尝试所有可能的分割方式,直到找到一个所有子字符串都是回文串的分割方式。

代码实现

现在,让我们来看看 Python 代码的具体实现吧!

动态规划

def is_palindrome(s):
  """
  判断一个字符串是否是回文串

  Args:
    s: 字符串

  Returns:
    布尔值,表示 s 是否是回文串
  """

  return s == s[::-1]


def palindrome_partitioning_dp(s):
  """
  使用动态规划解决 Palindrome Partitioning 问题

  Args:
    s: 字符串

  Returns:
    所有可能的分割方式的列表,其中每个子字符串都是回文串
  """

  n = len(s)
  dp = [[False] * n for _ in range(n)]

  for i in range(n):
    dp[i][i] = True

  for length in range(2, n + 1):
    for i in range(n - length + 1):
      j = i + length - 1
      if length == 2:
        dp[i][j] = s[i] == s[j]
      else:
        dp[i][j] = dp[i + 1][j - 1] and s[i] == s[j]

  partitions = []

  def backtrack(i, path):
    if i == n:
      partitions.append(path)
      return

    for j in range(i, n):
      if dp[i][j]:
        backtrack(j + 1, path + [s[i:j + 1]])

  backtrack(0, [])

  return partitions


**深度优先搜索** 

```python
def palindrome_partitioning_dfs(s):
  """
  使用深度优先搜索解决 Palindrome Partitioning 问题

  Args:
    s: 字符串

  Returns:
    所有可能的分割方式的列表,其中每个子字符串都是回文串
  """

  partitions = []

  def is_palindrome(s):
    """
    判断一个字符串是否是回文串

    Args:
      s: 字符串

    Returns:
      布尔值,表示 s 是否是回文串
    """

    return s == s[::-1]

  def backtrack(i, path):
    if i == len(s):
      partitions.append(path)
      return

    for j in range(i, len(s)):
      if is_palindrome(s[i:j + 1]):
        backtrack(j + 1, path + [s[i:j + 1]])

  backtrack(0, [])

  return partitions

结语

恭喜你,你已经成功地掌握了两种解决 LeetCode 131 题:Palindrome Partitioning 的方法:动态规划和深度优先搜索。希望这些知识能够帮助你更轻松地应对算法难题,也希望你能够继续探索更多有趣的算法问题。如果你有任何疑问或建议,欢迎在评论区留言。让我们一起在算法的世界中继续前行,不断进步!