很多人用双端队列,其实用数组标记删除位置再输出未删除的字符更简单,没学过队列也能做。

核心思想就是用数组标记当前字符位置是否已删除,用左指针和右指针标记光标两侧未删除的首个字符。根据不同操作,边标记边移动指针即可。

#include <iostream>
#include <vector>
using namespace std;
int main() {
    int n, k;
    string s, op;
    cin >> n >> k;
    cin >> s;
    //用数组标记当前位置是否被删除
    vector<bool>isDelete(n, false);
    int pos = s.find('I');//光标位置
    int l = pos - 1, r = pos + 1;//定义左指针和右指针
    while (k--) {
        cin >> op;
        //按照题目规则操作即可,每删除一次指针移动一步
        if (op == "backspace") {
            if (l >= 0 && r < n && s[l] == '(' && s[r] == ')') {
                isDelete[l--] = true;
                isDelete[r++] = true;
            } else if (l >= 0)
                isDelete[l--] = true;
        } else if (r < n)
            isDelete[r++] = true;
    }
    //由于n比较大,所以这里不判断标记,直接扫描未删除的区间
    for (int i = 0; i <= l; i++)cout << s[i];
    cout << 'I';//不要忘记中间的I
    for (int i = r; i < n; i++)cout << s[i];
}