[路飞]844. 比较含退格的字符串

138 阅读2分钟

题目描述

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

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

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

分析

输入:string, string. 两个字符串
输出:Boolean, 表示两个字符串是否相等

解题思路

对于一般的解法,把两个字符串用两个栈进行保存,分别遍历保存字符,遇到 #,则弹出一位,最后看两个栈是否完全一致,这种做法需要消耗 O(N) 的空间,很不划算,我们看能不能用 O(1) 的空间消耗。

在这里,我们的方法是双指针,其核心思想是看指针指向的两个 char 是否相等,如果不等,返回 false

OK,然后我们怎么初始化指针,以及怎么遍历呢?

可以看到啊,每个 # 实际上影响的是前一个字符,前一个字符会被删去,那么我们根据这条就可以从后向前去记录 # 的个数,有几个就删除几个字符,那么指针相应地也就是从字符串最后一位开始。

如果遍历到 #,我们需要暂停一下,先处理当前字符串,记录需要删除的字符个数 skip,让指针减小,skip 增加,再向前找有没有 #,直到消除了 skip 的影响,我们再继续向下走。

对于另一个字符串,我们进行相同的操作。

然后比较当前指针的指向,是否相同,不同则返回 true。如果遍历完成,则说明相等,返回 true

代码

/**
 * @param {string} s
 * @param {string} t
 * @return {boolean}
 */
var backspaceCompare = function (s, t) {
  let p1 = s.length - 1,
    p2 = t.length - 1,
    skip1 = 0,
    skip2 = 0

  while (p1 > 0 || p2 > 0) {
    while (p1 > 0) {
      if (s[p1] === "#") {
        skip1++, p1--
      } else if (skip1 > 0) {
        skip1--, p1--
      } else {
        break
      }
    }

    while (p2 > 0) {
      if (t[p2] === "#") {
        skip2++, p2--
      } else if (skip2 > 0) {
        skip2--, p2--
      } else {
        break
      }
    }

    if (s[p1] !== t[p2]) return false
  }

  return true
}

/**
 * @param {string} s
 * @param {string} t
 * @return {boolean}
 */
var backspaceCompare = function (s, t) {
  let p1 = s.length - 1,
    p2 = t.length - 1,
    skip1 = 0,
    skip2 = 0

  while (p1 >= 0 || p2 >= 0) {
    while (p1 >= 0) {
      if (s[p1] === "#") {
        skip1++, p1--
      } else if (skip1 > 0) {
        skip1--, p1--
      } else {
        break
      }
    }

    while (p2 >= 0) {
      if (t[p2] === "#") {
        skip2++, p2--
      } else if (skip2 > 0) {
        skip2--, p2--
      } else {
        break
      }
    }

    if (s[p1] !== t[p2]) return false
    p1--
    p2--
  }

  return true
}

复杂度

时间:O(N), 需要遍历字符串
空间:O(1), 自需要保存指针