栈和队列4:删除字符串中相邻的相同元素

思路

思路很类似下面这个问题:
栈和队列5:用栈检测括号是否匹配

删除字符串更简单一些,很像我们玩的“消消乐”。
具体思路在代码注释,也可以结合上面的括号检测一起理解。

#include <iostream>
#include <stack>
#include <algorithm>

using namespace std;

class Solution {
public:
    string removeDuplicates(string s) {
        stack<char> st;
        for (char i : s) {
            //下面这两种情况进栈
            //1.栈为空
            //2.栈顶元素和现在正在扫描的字符i不同
            if (st.empty() || st.top() != i) {
                st.push(i);
            } else {
                //当栈顶元素和目前正在扫描的元素相同时,出栈
                st.pop();
            }
        }

       string result = "";//定义一个字符串变量保存结果
       while ( !st.empty()) {
           //若st不为空,则出将栈顶元素赋值
           result += st.top();
           st.pop();
       }

       //由于上面从栈复制到result的元素顺序是反的,所以使用resvers函数翻转一下
       reverse(result.begin(), result.end());

       return result;
    }
};
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是C语言的另一种实现方式,使用了队列来模拟手拉手离开队列的过程。 ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_N 100 // 定义队列结构体 typedef struct { int *data; // 队列元素数组指针 int head; // 队首位置 int tail; // 队尾位置 int size; // 队列大小 } Queue; // 初始化队列 void init_queue(Queue *q, int size) { q->data = (int *)malloc(sizeof(int) * size); q->head = 0; q->tail = 0; q->size = size; } // 销毁队列 void destroy_queue(Queue *q) { free(q->data); } // 判断队列是否为空 int is_empty(Queue *q) { return q->head == q->tail; } // 判断队列是否已满 int is_full(Queue *q) { return (q->tail + 1) % q->size == q->head; } // 入队 void enqueue(Queue *q, int val) { if (is_full(q)) { printf("队列已满,无法入队!\n"); return; } q->data[q->tail] = val; q->tail = (q->tail + 1) % q->size; } // 出队 int dequeue(Queue *q) { if (is_empty(q)) { printf("队列为空,无法出队!\n"); return -1; } int val = q->data[q->head]; q->head = (q->head + 1) % q->size; return val; } int main() { char queue[MAX_N + 1]; // 输入字符串队列最大长度为100,需要多一个字符存储'\0' int boy[MAX_N / 2], girl[MAX_N / 2]; // 小男孩和小女孩的编号数组 Queue q; // 小男孩队列 int n, i, j; int boy_pos = 0; // 小男孩队列的队首位置 int girl_pos = 0; // 小女孩队列的队首位置 scanf("%s", queue); // 读入队列字符串 n = strlen(queue); // 队列长度 // 将小男孩和小女孩的编号分别存储在两个数组 for (i = 0; i < n; i++) { if (queue[i] == 'B') { boy[boy_pos++] = i; } else { girl[girl_pos++] = i; } } // 初始化小男孩队列 init_queue(&q, boy_pos); for (i = 0; i < boy_pos; i++) { enqueue(&q, boy[i]); } // 模拟手拉手离开队列的过程 for (i = 0; i < girl_pos; i++) { // 找到与当前小女孩手拉手离开队列的小男孩的编号 int boy_num; while (1) { boy_num = dequeue(&q); // 出队一个小男孩 if (boy_num > girl[i]) { // 如果当前小男孩编号比当前小女孩编号大,说明还没有找到与其手拉手离开队列的小女孩 enqueue(&q, boy_num); // 将该小男孩重新入队 } else { // 找到了与当前小女孩手拉手离开队列的小男孩 break; } } // 输出编号对 printf("%d %d\n", boy_num, girl[i]); } // 销毁队列 destroy_queue(&q); return 0; } ``` 这个实现方式使用了自定义的队列数据结构,避免了手动移动数组元素的麻烦。具体实现细节见注释。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

辛伯达岛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值