前端路漫漫-Day90:回文子串(题号647)
2024-02-22 09:10:52
从算法角度出发,回文子串一直是个颇有挑战性的问题,今天,我们将探讨如何利用动态规划来解决LeetCode第647题——“回文子串”。在这个问题中,给定一个字符串,要求计算这个字符串中有多少个回文子串。回文子串是指从字符串中提取出的子串,无论正着读还是倒着读,都是一样的。
我们首先定义dp[i][j]为字符串s[i:j]的回文子串个数,其中s[i:j]表示字符串s从下标i到下标j的子串。显然,当i>j时,s[i:j]是一个空串,它的回文子串个数为0。
其次,考虑如何计算dp[i][j]。如果s[i]=s[j],那么s[i:j]是一个回文子串,它的回文子串个数为dp[i+1][j-1] + 2。其中dp[i+1][j-1]表示s[i+1:j-1]的回文子串个数,2表示s[i]和s[j]各有一个回文子串。
如果s[i]!=s[j],那么s[i:j]不是一个回文子串,它的回文子串个数为dp[i+1][j] + dp[i][j-1]。其中dp[i+1][j]表示s[i+1:j]的回文子串个数,dp[i][j-1]表示s[i:j-1]的回文子串个数。
综上,我们可以得到动态规划的转移方程:
dp[i][j] =
if s[i] == s[j] and i + 1 <= j - 1: dp[i+1][j-1] + 2
if s[i] != s[j] or i + 1 > j - 1: dp[i+1][j] + dp[i][j-1]
有了动态规划的转移方程,我们就可以通过自底向上的方式计算出dp[i][j],并最终得到字符串s的回文子串个数。
最后,我们来看一个例子。给定字符串s = "abba",我们使用动态规划来计算它的回文子串个数。
首先,我们计算出dp[1][1],dp[1][1] = 1,因为s[1:1]是一个回文子串。
接下来,我们计算出dp[1][2],dp[1][2] = 3,因为s[1:2]是一个回文子串,s[1]和s[2]各有一个回文子串。
然后,我们计算出dp[2][2],dp[2][2] = 5,因为s[2:2]是一个回文子串,s[1]和s[2]各有一个回文子串,s[1:2]是一个回文子串。
以此类推,我们可以计算出所有的dp[i][j],并最终得到字符串s的回文子串个数为16。
回文子串是算法领域的一个经典问题,它不仅考察了算法设计的基本功,还考察了算法优化的方法。通过动态规划来解决回文子串问题,可以让我们更好地理解动态规划的原理和应用,并提高我们解决算法问题的水平。