力扣 844. 比较含退格的字符串

46 阅读1分钟

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

题目链接

844. 比较含退格的字符串 - 力扣(LeetCode)

题目描述

给定 s 和 t 两个字符串,当它们分别被输入到空白的文本编辑器后,如果两者相等,返回 true 。# 代表退格字符。

注意:如果对空文本输入退格字符,文本继续为空。

测试用例

用例1:

输入: s = "ab#c", t = "ad#c"
输出: true
解释: s 和 t 都会变成 "ac"

限制

  • 1 <= s.length, t.length <= 200
  • s 和 t 只含有小写字母以及字符 '#'

题目分析

由题知,# 表示退格,会忽略掉他前面的一个字符。如下所示,展现转化后的字符:

abc# -> ac
abc## -> a
abc### -> ''
abc#### -> ''

对于这种风格,和栈非常的类似

对于所有的字符,一个个的压入到 栈,当遇到字符 # 时,把栈的最后一个元素弹出

代码实现

完整的代码实现如下

/**
 * @param {string} s
 * @param {string} t
 * @return {boolean}
 */
var backspaceCompare = function(s, t) {
    return dealStr(s) == dealStr(t);

    function dealStr(str) {
        let stack = [];
        for (let i = 0; i < str.length; i++) {
            let c = str.charAt(i);
            if (c == '#') {
                stack.pop();
            } else {
                stack.push(c)
            }
        }
        return stack.join('')
    }
};

image.png

来实现,代码简洁明了

双指针解法

通过对测试样例的分析,可以发现一个规律,我们可以从后往前挨个遍历字符,当遇到字符 # 的时候,就需要将指针往前移 2 步:1、是忽略 # 这个元素;2、# 所代表的 ”退格“ 需要再往前挪一步

所以,比较的方式就变成了,用两个指针,分别指向两个字符的末尾字符串,处理好 # 字符,找到正确含义的字符,挨个比较,相同就将指针往前移;不同,就直接返回 false

1.gif

var backspaceCompare = function (s, t) {
    let flag = true;
    for (let p1 = s.length - 1, p2 = t.length - 1; p1 > -1 || p2 > -1; p1--, p2--) {
        p1 = getNextCharIndex(s,p1);
        p2 = getNextCharIndex(t,p2);
        if (s.charAt(p1) != t.charAt(p2)) {
            flag = false;
            break;
        }
    }
    return flag;
};
function getNextCharIndex(s, l = s.length - 1) {
    let f = 0;
    while (true) {
        if (s.charAt(l) == '#') {
            f+=2;
        }
        if (f-- <= 0) {
            break;
        }
        l--;
    }
    return l;
}

image.png

双指针的难点在于,如何获取到 ”正确“ 的字符,因此,我将这个获取的动作,单独封装成了函数,代码也变得容易阅读