LeetCode 算法:一次编辑

88 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第 5 天,点击查看活动详情

一次编辑

原题地址

字符串有三种编辑操作:插入一个英文字符、删除一个英文字符或者替换一个英文字符。 给定两个字符串,编写一个函数判定它们是否只需要一次(或者零次)编辑。

示例 1:

输入: 
first = "pale"
second = "ple"
输出: True

示例 2:

输入: 
first = "pales"
second = "pal"
输出: False

示例 3:

输入: 
first = "teacher"
second = "teecher"
输出: True

思路分析

  1. 分析题目,按照题目描述,如果一个字符串想要经过一次编辑转换成另一个字符串,需要先判断它俩的长度;
  2. 若长度差大于1,那么它们无论如何都不可能一次变换成功;
  3. 若长度相同,那么只需要遍历两个字符串,把相同位置不相同的字符记下来,然后判断不相同的字符是否超过了一个,若超过一个也表明无法一次变换成功;
  4. 若两个字符串的长度差等于1,那么也就意味着,长度比较长的那个字符串在去掉每个字符后组成的跟长度比较短的那个字符串长度相同的结果数组中,肯定包含长度比较短的那个字符串;因此定义一个 getArrs 方法,来获取长度比较长的字符串组成的长度比较短的字符串的结果「若字符串为 abcd, 那么得到的结果数组为 ['bcd', 'acd', 'abd', 'abc']」;
  5. 经过上述三步,即可判断两个字符串是否可以通过一次编辑进行变换。

AC 代码

/**
 * @param {string} first
 * @param {string} second
 * @return {boolean}
 */
var oneEditAway = function(first, second) {
    const len1 = first.length
    const len2 = second.length
    if(Math.abs(len1 - len2) > 1) return false
    if(len1 === len2) {
        const res = []
        for(let i = 0; i < len1; i++) {
            if(first[i] !== second[i]) {
                res.push(first[i])
            }
        }
        return res.length <= 1
    }
    if(Math.abs(len1 - len2) === 1) {
        const arr = getArrs(len1 > len2 ? first.split('') : second.split(''))
        return arr.includes(first) || arr.includes(second)
    }
};

var getArrs = function(arr) {
    const res = []
    for(let i = 0; i < arr.length; i++) {
        var newarr = arr.slice(0)
        newarr.splice(i, 1)
        res.push(newarr.join(''))
    }
    return res
}

结果:

  • 执行结果: 通过
  • 执行用时:96 ms, 在所有 JavaScript 提交中击败了5.70%的用户
  • 内存消耗:43.4 MB, 在所有 JavaScript 提交中击败了15.09%的用户
  • 通过测试用例:1146 / 1146

END