二十天刷题计划--双指针(2)

99 阅读1分钟

「这是我参与2022首次更文挑战的第13天,活动详情查看:2022首次更文挑战」。

1.题目

比较含退格的字符串

给定 s 和 t 两个字符串,当它们分别被输入到空白的文本编辑器后,请你判断二者是否相等。# 代表退格字符。

如果相等,返回 true ;否则,返回 false 。

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

 

示例 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 = "#a#c" 输出:true 解释:s 和 t 都会变成 “c”。

示例 4:

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

提示:

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


思路

同时从后向前遍历S和T(i初始为S末尾,j初始为T末尾),记录#的数量,模拟消除的操作,如果#用完了,就开始比较S[i]和S[j]。

如果S[i]和S[j]不相同返回false,如果有一个指针(i或者j)先走到的字符串头部位置,也返回false。


代码

var backspaceCompare = function(S, T) {
  let sEnd = S.length - 1;
  let tEnd = T.length - 1;
  let sStart = 0;
  let tStart = 0;

  // 注意,只要有一个还没有结束,就继续下去
  // 内部有判断 0 逻辑
  while (sEnd >= 0 || tEnd >= 0) {
    while (sEnd >= 0) {
      if (S.charAt(sEnd) === '#') {
        sEnd--;
        // 通过sStart代表一个位删除
        // 为什么会移动两位(sStart + 1,sEnd - 1)
        // 因为算上 # 本身,实际上移除了两位字符
        sStart++;
      } else if (sStart > 0) {
        // 向左滑动窗口到左对其
        // 右边代表已经删完了
        sStart--;
        sEnd--;
      } else break;
    }

    while (tEnd >= 0) {
      if (T.charAt(tEnd) === '#') {
        tEnd--;
        tStart++;
      } else if (tStart > 0) {
        tStart--;
        tEnd--;
      } else break;
    }
    
    // 有一个 end 已经出界了,-1
    // 如果两个都出界了,那就结束循环了,相等
    if ((sEnd >= 0) && (tEnd >= 0)) {
      return false;
    }

    if (S.charAt(sEnd) !== T.charAt(tEnd)) {
      return false;
    }

    // 没触发跳出,说明最右边一位相等
    // 继续向左比较
    sEnd--;
    tEnd--;
  }

  return true;
};