844. 比较含退格的字符串

46 阅读2分钟

💡未完成:需要多看、多思考。带入字符进行调试

题目

🔗题目链接:844. 比较含退格的字符串 - 力扣(LeetCode)

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

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

示例 1:

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

示例 2:

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

示例 3:

输入: s = "a#c", t = "b"
输出: false
解释: s 会变成 "c",但 t 仍然是 "b"

提示:

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

进阶:

  • 你可以用 O(n) 的时间复杂度和 O(1) 的空间复杂度解决该问题吗?

思路

字符串是不可变的,所以不能对字符串元素进行类似数组的删除和移动操作,正确方式是进行字符对比。因为有退格字符,从前往后对比的话复杂度很高。所以从后往前逆序对字符进行对比。

代码

function backspaceCompare(s: string, t: string): boolean {
  // 从后往前遍历
  let sPointer = s.length - 1;
  let tPointer = t.length - 1;
  // 在每次循环的时候记录退格符的个数
  let skipS = 0;
  let skipT = 0;

  // 在这个循环里,在两个字符串之间,一次比较一个字符,有一次的比较结果不一致就返回 false
  while (sPointer >= 0 || tPointer >= 0) {
      
    // 每次循环会找出一个有效的字符(不被退格符影响的字符串)
    while (sPointer >= 0) {
      if ("#" === s[sPointer]) {
        skipS++;
        sPointer--;
      } else if (skipS > 0) {
        skipS--;
        sPointer--;
      } else {
        break;
      }
    }

    // 每次循环会找出一个有效的字符(不被退格符影响的字符串)
    while (tPointer >= 0) {
      if ("#" === t[tPointer]) {
        skipT++;
        tPointer--;
      } else if (skipT > 0) {
        skipT--;
        tPointer--;
      } else {
        break;
      }
    }

    
    if (sPointer >= 0 && tPointer >= 0) {
      // 指的是下面这一行 if
      // 对应的字符不相等 
      if (s[sPointer] !== t[tPointer]) return false;
      
    } else {
      // 指的是下面这一行 if
      // 因为是 else
      // sPointer 和 tPointer 必不可能同时大于等于 0
      // ⚠需要再次思考!!!
      if (sPointer >= 0 || tPointer >= 0) return false;
      
    }

    sPointer--;
    tPointer--;
  }

  return true;
}