携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第29天,点击查看活动详情
描述
给你两个字符串str1和str2,使得str1和str2相同的最小步数。
每步可以删除str1和str2字符串的任意字符。
例如:
两个字符分别是leetcode和etco。
我们可以看出leetcode中包含etco,那我们需要做的就是删除leetcode中的前后各2个字符,总共是4个字符,需要4步就可以完成。所以结果返回4。
这里我们给出一个限制:
给出的两个字符串处理后得到的相同字符串在两个字符串中都是连续的。
分析
如果给出的两个字符串没有任何相同的字符,那我们想让它们相同,只能都是空字符串了,这种情况下返回的结果都是两字符串长度和,因为要全部删除才都是空字符串。
另一种情况就是存在相同字符了。题目是要求得到最小的步数,那我们必须得找出最大连续的公共子串,之所以说连续,是因为描述中给出了一个限制,处理后的子串在两者中都是连续的,子串长度越大,那就说明需要操作的步数最小。
要找出最长子串,我们就得从可能的最大公共字符串开始,逐步再取子串判断,那什么可能是最大公共子串呢?
给出的两个字符串长度较小的就可能是,就像描述中的例子,etco就是最大的子串,也是给出的字符串之一。
我们判断的时候要不断用阶段固定长度平移的方式,这样我们才能不断取到连续的子串。
思路其实挺简单,但如果我们把描述中的限制去掉呢?子串并非一定连续,我们可以删除目标字符串的任意中间字符,就要更难一点,思路不一样,该如何实现呢?
程序实现
根据以上分析,具体代码实现如下:
// 公共子串最长,那步数必定最小,并且如果从最长开始删,那第一个相等则直接返回即可
const len1 = word1.length
const len2 = word2.length
let tar = len1 > len2 ? word2 : word1
for (let i = 0; i < tar.length; i++) {
for (let j = 0; j < tar.length; j++) {
if (j-i > 0) continue
// 从j下标开始平移
let str = tar.slice(j, j+tar.length-i)
// 判断相等
if (word1.includes(str) && word2.includes(str)) {
return len1 + len2 - (str.length * 2)
}
}
}
// 如果两者没有任何相同的字符
return len1 + len2