1143. 最长公共子序列
题目描述
给定两个字符串 \(text1\) 和 \(text2\),返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 ,返回 \(0\) 。
一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。
- 例如,
"ace"
是"abcde"
的子序列,但"aec"
不是"abcde"
的子序列。
两个字符串的 公共子序列 是这两个字符串所共同拥有的子序列。
示例 1:
1 2 3 |
|
示例 2:
1 2 3 |
|
示例 3:
1 2 3 |
|
提示:
- \(1\) \(≤\) \(text1.length, text2.length\) \(≤\) \(1000\)
- \(text1\) 和 \(text2\) 仅由小写英文字符组成。
算法与思路
动态规划 \(O(n^2)\)
状态 \(dp[i][j]\)
-
定义:\(test1\) 的前 \(i\) 个字母 和 \(test2\) 的前 \(j\) 个字母 的组成的公共子序列的集合。
-
属性:子序列长度的最大值。
状态转移:
-
\(test1[i] ≠ test2[j]\) 时
- \(test1[i]\) 不包含在最长公共子序列中;
- \(test2[j]\) 不包含在最长公共子序列中。
根据状态的定义,可以得出\(a\)情况可以用 \(dp[i - 1][j]\) 的状态表示;同理,\(b\)情况可以用 \(dp[i][j - 1]\) 的状态表示。
-
\(test1[i] = test2[j]\) 时
可以由 \(dp[i - 1][j - 1] + 1\) 来表示。
最后可以根据状态的定义,可以得知,\(dp[n][m]\) 为最终答案。
复杂度分析:
时间复杂度:\(O(nm)\) 。每次计算一个 \(test1\) 的字符,就要遍历一遍 \(test2\) 的所有字符。
空间复杂度:\(O(nm)\) 。需要 \(n\) 行 \(m\) 列的 \(dp\) 数组来存储状态。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|