牛牛拿到了一个字符串。
他每次“点击”,可以把字符串中相邻两个相同字母消除,例如,字符串"abbc"点击后可以生成"ac"。
但相同而不相邻、不相同的相邻字母都是不可以被消除的。
牛牛想把字符串变得尽可能短。他想知道,当他点击了足够多次之后,字符串的最终形态是什么?
输入描述:
一个字符串,仅由小写字母组成。(字符串长度不大于300000)
输出描述:
一个字符串,为“点击消除”后的最终形态。若最终的字符串为空串,则输出0。
示例1
输入:abbc
复制输出:ac
输入:abba
输出:0
输入:bbbbb
输出:b
思路:引入栈的数据结构进行完成
- 引入辅助栈stk,遍历字符串,每次遇到与栈顶相同的字符就栈顶元素出栈
- 栈为空或者当前字符与栈顶元素不等,就当前元素入栈
- 输出结果,栈空说明最终是空串,直接输出0
- 如果不是空串就再引入一个栈来逆置字符输出
#include<stdio.h>
#include <stdlib.h>
struct node {
char data;
struct node* next;
};
struct node* xiao_chu(char* p) {
struct node* tail = malloc(sizeof(struct node));
tail->next = NULL;
int i = 0;
while (*(p + i) != '\0') {
if (tail->next == NULL) {
struct node* pnew = malloc(sizeof(struct node));
pnew->data = *(p + i);
pnew->next = tail->next;
tail->next = pnew;
} else if (tail->next->data != *(p + i)) {
struct node* pnew1 = malloc(sizeof(struct node));
pnew1->data = *(p + i);
pnew1->next = tail->next;
tail->next = pnew1;
} else if (tail->next->data == *(p + i)) {
struct node* l = tail->next;
tail->next = l->next;
l->next = NULL;
free(l);
l = NULL;
}
i++;
}
if (tail->next == NULL) {
printf("0 ");
} else {
//引入一个新的栈来逆序输出结果
//并没有创建新的数据结点,为了最大节省内存空间,选择将原先栈节点按出栈的顺序入栈新的栈
struct node* tail1 = malloc(sizeof(struct node));
tail1->next = NULL;
struct node* f = tail->next;
while (f != NULL) {
tail->next = f->next;
f->next = tail1->next;
tail1->next = f;
f = tail->next;
}
while (tail1->next != NULL) {
printf("%c ", tail1->next->data);
tail1->next = tail1->next->next;
}
}
while (tail->next != NULL) {
printf("%c ", tail->next->data);
tail = tail->next;
}
}
int main() {
char a[10];
scanf("%s", a);
char* pre = a;
xiao_chu(pre);
}
本人才疏学浅,若有不足欢迎指正!