力扣844. 比较含退格的字符串

比较含退格的字符串题目

思路

有两个思路。

第一个思路是最容易想到的,用栈来保存字符,遇到’#‘则弹出一个元素即可,唯一要注意的是遇到’#'弹出时检查一下栈是否为空。不过这种做法是需要额外空间的。

第二个思路是重构字符串,把被回退的字符忽略掉。
由于’#‘本身就是在比较时要忽略的,因此把被回退的字符改为’#'更方便比较。

使用两个指针分别遍历两个重构后的字符串,若遇到’#‘则忽略,然后比较字符。要注意在忽略’#‘时可能会越界,因此每次检查’#'并递增后需要判断一下。
在思路一中用栈处理时,若两个栈长度不等则一定字符串不相等,但在思路二中可能存在字符串不等长但却相等的情况。因此在比较的时候要注意停止比较的条件。
我用第一个字符串s的遍历结束作为停止比较的条件。此时有三种情况:

  • 第二个字符串t也遍历结束,这说明s和t是相等的
  • t剩下没遍历的字符都是’#',此时s和t也是相等的
  • t还有非‘#’字符没有遍历到,这说明s和t不相等

思路一代码

class Solution {
public:
    bool backspaceCompare(string s, string t) {
        stack<char> stack1; stack<char> stack2;
        int sLength = s.length(), tLength = t.length();
        int i = 0;
        // 入栈
        while (i < sLength) {
            if (s[i] != '#')
                stack1.push(s[i]);
            else if (!stack1.empty())
                stack1.pop();
            i++;
        }
        // 相同方法处理t
        i = 0;
        while (i < tLength) {
            if (t[i] != '#')
                stack2.push(t[i]);
            else if (!stack2.empty())
                stack2.pop();
            i++;
        }
        // 比较
        if (stack1.size() != stack2.size())
            return false;

        i = 0;
        while (!stack1.empty()) {
            if (stack1.top() != stack2.top())
                return false;
            stack1.pop();   stack2.pop();
        }
        return true;
    }
};

思路二代码

class Solution {
private:
    void backspace(string& s) {
        // 遍历s和t,将每个#前的第一个字母改为'#'
        int i = 0;
        while (i < s.length()) {
            // 找到'#'
            if (s[i] != '#') {
                i++;
                continue;
            }
            // 找到'#'前的第一个字母
            int j = i++;
            while ( j >= 0 && s[j] == '#') {
                j--;
            }
            if (j < 0)
                continue;
            // 将其改为'#'
            s[j] = '#';
        }
    }
public:
    bool backspaceCompare(string s, string t) {
        backspace(s);   backspace(t);
        int sLength = s.length(), tLength = t.length();
        // 比较
        int i = 0, j = 0;
        while (i < sLength) {
            // 忽略'#'
            while (s[i] == '#') {
                i++;
                // s遍历完了
                if (i == sLength)
                    // 若t也结束了或只剩下'#',则相同,否则不同
                    break;
            }
            // 此时s要么结束了,要么停在了不是#的地方
            if (j == tLength)
                // 若s结束了,则相同,否则不同
                return i == sLength;
            while (t[j] == '#') {
                j++;
                // 和上面同理
                if (j == tLength) {
                    return i == sLength;
                }
            }
            // 比较
            if (s[i++] != t[j++])
                return false;
        }
        // 此时s遍历完了,若t也遍历完则相同
        if (j == tLength)
            return true;
        // 忽略剩下的'#'
        while (t[j] == '#') {
            j++;
            if (j == tLength)
                return true;
        }
        // 此时t还有剩下的但s已经完了
        return false;
    }
};

你可能感兴趣的:(算法题解,leetcode,算法,数据结构)