算法刷题自记录 | Leetcode844. 比较含退格的字符串(双指针)

给定两个字符串`s`和`t`,在考虑#号为退格字符的情况下,判断它们是否能通过退格操作变得相等。文章介绍了使用双指针从右向左遍历的方法来解决这个问题,重点在于处理#号和字符的匹配逻辑,并给出了Python3的实现代码。题目要求在O(n)的时间复杂度和O(1)的空间复杂度下完成。
摘要由CSDN通过智能技术生成

题目

题目描述:给定 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) 的空间复杂度解决该问题吗?

思路

  本质是一个双指针问题。因为 # 号只会删除左边的字符,对 # 号右边的字符没有影响,所以可以从右往左遍历 s, t 字符串。

  遍历思路:

        1. 声明两个分别指向 s 和 t 末位字符的指针i, j,以及两个用于保存 st 中 # 号数量的参数skips, skipt

        2. 从右往左遍历 s,会有三种情况:

                ① 当前字符为 # 号        =>        skips 加1

                ② 当前字符不为 # 号,且skips不为0        =>        skips 减1 

                ③ 当前字符不为 # 号,且skips为0        =>        停止遍历

        3. 从右往左遍历 t,情况同上。

        4. 判断当前字符是否匹配,这里是一个需要注意的点,具体判断依据参考代码中的注释,结合代码看会容易理解一些。

Python3代码

  • 时间复杂度:O(N+M)。其中 N 和 M 分别为两个字符串的长度。因为需要遍历两个字符串各一遍。
  • 空间复杂度:O(1)
class Solution:
    def backspaceCompare(self, s: str, t: str) -> bool:
        i, j = len(s) - 1, len(t) - 1        # 指针,分别指向 s 和 t 的末位字符
        skips = skipt = 0                    # 用于保存 s 和 t 中 # 号的数量
        while i >= 0 or j >= 0:
            while i >= 0:                    # 从右往左遍历s
                if s[i] == '#':              # 遇 # 号,skips加1
                    skips += 1
                    i -= 1
                elif s[i] != '#' and skips:  # 遇非 # 号字符,但skips不为0
                    i -= 1
                    skips -= 1               # 此时skips减1,接着向左遍历
                else:
                    break                    # 遇非 # 号字符,且skips为0,停止遍历

            while j >= 0:                    # 从右往左遍历t
                if t[j] == '#':
                    skipt += 1
                    j -= 1
                elif t[j] != '#' and skipt:
                    j -= 1
                    skipt -= 1
                else:
                    break

            ### 接下来需要寻找return False的情况。需要注意!
            if i >= 0 and j >= 0:
                if s[i] != t[j]:            # 待比较的字符不同,return False
                    return False
            # (i >= 0 and j >= 0)为False的情况有3种:
            # 1. i < 0 && j >= 0
            # 2. j < 0 && i >= 0
            # 3. i < 0 && j < 0 ==> 其中这种情况应该return True。
            #                       因为如果 index = 0 时字符为 # 号,index -= 1 后会变为-1
            # 所以接下来需要处理1.2.两种情况
            elif i >= 0 or j >= 0:
                return False

            i -= 1
            j -= 1

        return True

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值