We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
给定两个字符串 text1 和 text2,返回这两个字符串的最长公共子序列的长度。
一个字符串的子序列是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。 例如,"ace" 是 "abcde" 的子序列,但 "aec" 不是 "abcde" 的子序列。两个字符串的「公共子序列」是这两个字符串所共同拥有的子序列。
若这两个字符串没有公共子序列,则返回 0。
示例 1: 输入:text1 = "abcde", text2 = "ace" 输出:3 解释:最长公共子序列是 "ace",它的长度为 3。 示例 2: 输入:text1 = "abc", text2 = "abc" 输出:3 解释:最长公共子序列是 "abc",它的长度为 3。 示例 3: 输入:text1 = "abc", text2 = "def" 输出:0 解释:两个字符串没有公共子序列,返回 0。 提示: 1 <= text1.length <= 1000 1 <= text2.length <= 1000 输入的字符串只含有小写英文字符。
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/longest-common-subsequence 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
把两个字符长度都置为 1 开始规划基础状态,注意这是一个二维的 dp 数组, dp[m][n] 中的 m 和 n 分别代表字符串 1 的长度和字符串 2 的长度,这个坐标的状态就是「字符串 1 长度为 m 且字符串 2 长度为 n 时的最长公共序列长度」。
dp[m][n]
对于 dp[m][n] 来说,分为两种情况:
s1[m] === s2[n] 字符相等,那么就直接等于 1 + dp[m - 1][n - 1],也就是当前相等所得到的长度 1 加上两个字符各减去一位后的最长子序列长度。
s1[m] === s2[n]
1 + dp[m - 1][n - 1]
s1[m] !== s2[n] 字符不相等,那么就分别尝试把两边各减去一位,求它们的最长子序列长度中的 最大值,也就是 max(dp[m][n - 1], dp[m - 1][n])。
s1[m] !== s2[n]
max(dp[m][n - 1], dp[m - 1][n])
理清楚这个关系后,就可以开始写传统的二维数组 dp 求解了,动态规划是自底向上的,所以我们从字符位置都在 0 的情况开始,慢慢的向上求解。
0
注意这题里要提前把溢出情况比如 dp[-1][0]、dp[-1][-1] 提前设置为 0,防止访问时报错。比如在求解 dp[0][0] 并且两个字符串的第 0 位都相同的时候就会转而去求 dp[-1][-1]
dp[-1][0]
dp[-1][-1]
dp[0][0]
/** * @param {string} text1 * @param {string} text2 * @return {number} */ let longestCommonSubsequence = function (text1, text2) { let n1 = text1.length let n2 = text2.length let dp = [] for (let i1 = 0; i1 <= n1; i1++) { dp[i1] = [] dp[i1][0] = 0 } dp[0] = Array(n2 + 1).fill(0) for (let i1 = 1; i1 <= n1; i1++) { for (let i2 = 1; i2 <= n2; i2++) { let str1 = text1[i1 - 1] let str2 = text2[i2 - 1] if (str1 === str2) { dp[i1][i2] = 1 + dp[i1 - 1][i2 - 1] }else { dp[i1][i2] = Math.max(dp[i1 - 1][i2], dp[i1][i2 - 1]) } } } return dp[n1][n2] };
The text was updated successfully, but these errors were encountered:
No branches or pull requests
给定两个字符串 text1 和 text2,返回这两个字符串的最长公共子序列的长度。
一个字符串的子序列是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。
例如,"ace" 是 "abcde" 的子序列,但 "aec" 不是 "abcde" 的子序列。两个字符串的「公共子序列」是这两个字符串所共同拥有的子序列。
若这两个字符串没有公共子序列,则返回 0。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-common-subsequence
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
把两个字符长度都置为 1 开始规划基础状态,注意这是一个二维的 dp 数组,
dp[m][n]
中的 m 和 n 分别代表字符串 1 的长度和字符串 2 的长度,这个坐标的状态就是「字符串 1 长度为 m 且字符串 2 长度为 n 时的最长公共序列长度」。对于
dp[m][n]
来说,分为两种情况:s1[m] === s2[n]
字符相等,那么就直接等于1 + dp[m - 1][n - 1]
,也就是当前相等所得到的长度 1 加上两个字符各减去一位后的最长子序列长度。s1[m] !== s2[n]
字符不相等,那么就分别尝试把两边各减去一位,求它们的最长子序列长度中的 最大值,也就是max(dp[m][n - 1], dp[m - 1][n])
。理清楚这个关系后,就可以开始写传统的二维数组 dp 求解了,动态规划是自底向上的,所以我们从字符位置都在
0
的情况开始,慢慢的向上求解。注意这题里要提前把溢出情况比如
dp[-1][0]
、dp[-1][-1]
提前设置为 0,防止访问时报错。比如在求解dp[0][0]
并且两个字符串的第 0 位都相同的时候就会转而去求dp[-1][-1]
The text was updated successfully, but these errors were encountered: