day40-数据结构力扣

📅 2026/7/3 3:42:21 👁️ 阅读次数 📝 编程学习
day40-数据结构力扣

647. 回文子串

题目链接647. 回文子串 - 力扣(LeetCode)

思路

1. dp 数组定义

dp[i][j]:表示字符串下标 i 到 j 的子串是否是回文串,True是,False不是。

2. 递推公式

  • 情况 1:i == j(单个字符)→ 一定是回文

  • 情况 2:j = i+1(两个相邻字符)→s[i]==s[j]就是回文

  • 情况 3:j - i > 1(长度大于 2)首尾字符相等,且中间子串也是回文:dp[i][j]=(s[i]==s[j]) and dp[i+1][j−1]

3. 初始化

所有dp[i][i] = True,单个字符都是回文。

4. 遍历顺序

按子串长度从小到大遍历,先短后长。

5. 结果

遍历过程中统计所有dp[i][j] = True的总数。

提交

class Solution: def countSubstrings(self, s: str) -> int: n = len(s) # dp[i][j] 表示 s[i...j] 是否为回文子串 dp = [[False] * n for _ in range(n)] res = 0 # 遍历子串长度 len = 1 ~ n for length in range(1, n + 1): # 左端点i for i in range(n - length + 1): # 右端点j j = i + length - 1 if i == j: # 单个字符 dp[i][j] = True elif j == i + 1: # 两个字符 dp[i][j] = (s[i] == s[j]) else: # 多于两个字符:首尾相等且中间是回文 dp[i][j] = (s[i] == s[j]) and dp[i+1][j-1] # 是回文就计数+1 if dp[i][j]: res += 1 return res

516.最长回文子序列

题目链接516. 最长回文子序列 - 力扣(LeetCode)

思路

1. dp 定义

dp[i][j]:字符串下标 i~j的子串中,最长回文子序列长度

2. 递推公式

  • s[i] == s[j]:首尾字符相同,可以一起算进回文dp[i][j]=dp[i+1][j−1]+2

  • s[i] != s[j]:舍弃左或舍弃右,取最大值dp[i][j]=max(dp[i+1][j], dp[i][j−1])

3. 初始化

单个字符一定是回文:dp[i][i]=1

4. 遍历顺序

逆序遍历 i(从后往前),j 从 i+1 往后走。

为什么要逆序遍历i:

因为从递推公式里面看到,i是用i+1推出来的

5. 结果

dp[0][n-1]就是整个字符串最长回文子序列长度。

提交

class Solution: def longestPalindromeSubseq(self, s: str) -> int: n = len(s) # dp[i][j]:s[i...j] 最长回文子序列长度 dp = [[0] * n for _ in range(n)] # 初始化:单个字符 for i in range(n): dp[i][i] = 1 # i 逆序遍历 for i in range(n - 1, -1, -1): for j in range(i + 1, n): if s[i] == s[j]: dp[i][j] = dp[i+1][j-1] + 2 else: dp[i][j] = max(dp[i+1][j], dp[i][j-1]) return dp[0][n-1]