【LeetCode844】比较含退格的字符串(双栈or双指针)

简介: 如果不考虑用O ( 1 ) O(1)O(1)的空间复杂度,很容易想到这种添加,删除的步骤,可以用到栈的入栈和出栈,所以可以用2个栈模拟2条字符串的退格运算:

一、题目

image.png

提示:


1 <= s.length, t.length <= 200

s 和 t 只含有小写字母以及字符 ‘#’

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


二、法一:双栈法

如果不考虑用O ( 1 ) O(1)O(1)的空间复杂度,很容易想到这种添加,删除的步骤,可以用到栈的入栈和出栈,所以可以用2个栈模拟2条字符串的退格运算:

class Solution {
public:
    bool backspaceCompare(string s, string t) {
        stack<char>s1;
        stack<char>s2;
        for(int i = 0; i < s.size(); i++){
            if(s[i] == '#' && s1.size()!= 0){
                s1.pop();
            }else if(s[i] != '#'){
                s1.push(s[i]);
            }
        }
        for(int i = 0; i < t.size(); i++){
            if(t[i] == '#' && s2.size()!= 0){
                s2.pop();
            }else if(t[i] != '#'){
                s2.push(t[i]);
            }
        }
        return s1 == s2;
    }
};

三、法二:双指针法

定义两个双指针,分别指向2个字符串的末尾。

skip表示当前需要待删除的字符个数。

// 挺难的
// 特殊用例
// a a#a 所以要用while (i >= 0 || j >= 0) 要用||,确保碰到满足false的情况,或者双方都遍历完毕
// a ba 返回false的第一种情况,双方skip均为0时进行比较,发现当且仅当一边出界了(可以都出界)
// aa aa# 这也是第一种情况
// a b 返回false第二种情况,双方skip均为0时进行比较,发现双方均未出界,但不相等
// 除了上面两种情况,一律返回true
// 另一难点,处理#的时候,退出循环的唯一条件就是skip == 0并且不为#
class Solution {
public:
    bool backspaceCompare(string S, string T) {
        int i, j, skipS, skipT;
        i = S.size() - 1;
        j = T.size() - 1;
        skipS = skipT = 0;
        while (i >= 0 || j >= 0) {
            while (i >= 0) {
                if (S[i] == '#') {
                    skipS++;
                    i--;
                }
                else if (skipS > 0) {
                    skipS--;
                    i--;
                }
                else break;
            }
            while (j >= 0) {
                if (T[j] == '#') {
                    skipT++;
                    j--;
                }
                else if (skipT > 0) {
                    skipT--;
                    j--;
                }
                else break;
            }
            // 此时双方的skip都是0,即应该进行判断(前提是都没出界)
            if (i >= 0 && j >= 0) {
                if (S[i] != T[j]) return false; // 返回false的第一个条件
            }
            else { // 至少有一个出界,包含 1. 都出界(不做处理) 2. 当且仅当一个出界(返回false的第二个条件)
                if (i >= 0 || j >= 0) { // 这行代码表示当且仅当一个出界
                    return false;
                }
            }
            // 下面这两行容易忘
            // 在经历了两轮考察(即判断你是否满足false的条件)之后,如果你满足,就两边各退一步
            // 我在官方的基础上加了if语句避免不必要的--操作,虽然不影响最后的答案,但是增强了可读性
            // 因为这里的--实质上是针对此时还未出界的指针进行的操作
            if (i >= 0) i--;
            if (j >= 0) j--;
        }
        return true; // 执行到这,说明遍历完两边,都没发现满足false的情况,故返回true
    } 
};
相关文章
|
2月前
|
JavaScript
力扣3333.找到初始输入字符串Ⅱ
【10月更文挑战第9天】力扣3333.找到初始输入字符串Ⅱ
34 1
|
2月前
|
C++
Leetcode第43题(字符串相乘)
本篇介绍了一种用C++实现的字符串表示的非负整数相乘的方法,通过逆向编号字符串,将乘法运算转化为二维数组的累加过程,最后处理进位并转换为字符串结果,解决了两个大数相乘的问题。
25 9
|
2月前
|
算法 C++
Leetcode第八题(字符串转换整数(atoi))
这篇文章介绍了LeetCode上第8题“字符串转换整数(atoi)”的解题思路和C++的实现方法,包括处理前导空格、正负号、连续数字字符以及整数溢出的情况。
19 0
|
2月前
【LeetCode 22】459.重复的子字符串
【LeetCode 22】459.重复的子字符串
30 0
|
2月前
【LeetCode 20】151.反转字符串里的单词
【LeetCode 20】151.反转字符串里的单词
19 0
|
2月前
【LeetCode 19】541.反转字符串II
【LeetCode 19】541.反转字符串II
20 0
|
2月前
【LeetCode 18】6.2.反转字符串
【LeetCode 18】6.2.反转字符串
15 0
|
3月前
|
存储 人工智能 C语言
C语言程序设计核心详解 第八章 指针超详细讲解_指针变量_二维数组指针_指向字符串指针
本文详细讲解了C语言中的指针,包括指针变量的定义与引用、指向数组及字符串的指针变量等。首先介绍了指针变量的基本概念和定义格式,随后通过多个示例展示了如何使用指针变量来操作普通变量、数组和字符串。文章还深入探讨了指向函数的指针变量以及指针数组的概念,并解释了空指针的意义和使用场景。通过丰富的代码示例和图形化展示,帮助读者更好地理解和掌握C语言中的指针知识。
|
4月前
|
存储 算法
LeetCode第43题字符串相乘
LeetCode第43题"字符串相乘"的解题方法,通过使用数组存储乘积并处理进位,避免了字符串转换数字的复杂性,提高了算法效率。
LeetCode第43题字符串相乘