844. 比较含退格的字符串

146 阅读2分钟

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

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

题目描述

给定 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,如果前字符不为#,则入栈,为#则弹出栈顶元素(栈不为空时),存在两个栈ss,ts中,再对比一下栈内的内容是否一致即可得出结果。但是,我们也可用双指针来解决这个问题,我们可以直接通过对比字符串实际得最后一个字符来得出结果。

代码实现

class Solution {
public:
    bool backspaceCompare(string s, string t) {
        int m=s.size()-1,n=t.size()-1;    //双指针指向字符串末尾
        int skipS=0,skipT=0;              //记录#数量
        while(m>=0||n>=0){
            while(m>=0){
                if(s[m]=='#') {skipS++;m--;}       //当前元素为#,skipS++,移向下一位
                else if(skipS>0) {skipS--;m--;}    //当前元素为字符,且skipS>0,说明被删除了,消耗#,移向下一位
                else break;                       //当前元素为字符,且skipS=0,说明没被删除了,被保留了,即为当前字符串实际的最后一个字符
            }
             while(n>=0){                       //对t进行相同的处理
                if(t[n]=='#') {skipT++;n--;}
                else if(skipT>0) {skipT--;n--;}
                else break;
            }
            if(m>=0&&n>=0){                    //退出条件
            if(s[m]!=t[n]) return false;       //当前字符串实际的最后一个字符不等则整个必然不等
            }else if(m>=0||n>=0){
                return false;                 //字符串的长度不等
            }
            m--;n--;                      //下一轮循环

        }
        return true;                 //完全比较完毕
    } 
};

我们双指针从末尾开始比较,是因为#号,不会对之后的字符造成影响,从末尾开始比较方便编写代码。这里的双指针都是指向两个字符串实际的最后一个字符,进行比较后就可以有了结果。详细见注释

总结

上述内容使用双指针的算法思想,使用在两个字符串上同时使用双指针比较,通过两个指针在两个字符串的移动比较,在一个for循环下完成两个for循环的工作,大大优化了时间复杂度。