232.用栈实现队列
使用栈实现队列的下列操作:
push(x) -- 将一个元素放入队列的尾部。
pop() -- 从队列首部移除元素。
peek() -- 返回队列首部的元素。
empty() -- 返回队列是否为空。
思路:
1、push:直接放入栈1
2、pop:(考虑到栈2中的元素是先进入的,永远比栈1先输出)
情况1:栈2是空的,则把栈1元素输出至栈2(自然逆向)
情况2:栈2还有未输出的元素
——输出栈2的第一个元素
3、peek:可以基于pop算法,但是并不需要pop掉,故而再放回(不要直接复制)
4、empty:两个链表都空,表明队列空
**注意:
create:
- create的过程中是需要开辟空间的!!
-对于栈和队列的情况,create的时候 为top /front rear指针赋值
-对于创建create函数可以这样写:返回mystack的指针
MyStack* myStackCreate() {
MyStack *s=(MyStack *)malloc(sizeof(MyStack));
s->front=s->rear=-1;
return s;
}
typedef struct:
注意给data [MAXSIZE],有时候会忘记写 [MAXSIZE]
i++ & ++i :
单独情况:++i和i++,效果都是i=i+1。
实际上:i++是先赋值,然后再自增;++i是先自增,后赋值(++在前,先自增)。
代码:
typedef struct {
int data1[500],data2[500];
int top1,top2;
} MyQueue;
MyQueue* myQueueCreate() {
MyQueue *l=(MyQueue *)malloc(sizeof(MyQueue));
l->top1=-1;
l->top2=-1;
return l;
}
void myQueuePush(MyQueue* obj, int x) {
obj->top1++;
obj->data1[obj->top1]=x;
}
int myQueuePop(MyQueue* obj) {
int answer;
if(obj->top2==-1){//如果出栈空了的话,把新进入的 逆序放入
while(obj->top1>=0){
obj->top2++;
obj->data2[obj->top2]=obj->data1[obj->top1];
obj->top1--;
}
}
answer=obj->data2[obj->top2];
obj->top2--;
return answer;
}
int myQueuePeek(MyQueue* obj) {
int answer= myQueuePop(obj);
obj->top2++;
obj->data2[obj->top2]=answer;
return answer;
}
bool myQueueEmpty(MyQueue* obj) {
if(obj->top1==-1 && obj->top2==-1) return true;
return false;
}
void myQueueFree(MyQueue* obj) {
obj->top1=-1;
obj->top2=-1;
}
225. 用队列实现栈
使用队列实现栈的下列操作:
- push(x) -- 元素 x 入栈
- pop() -- 移除栈顶元素
- top() -- 获取栈顶元素
- empty() -- 返回栈是否为空
注意:
- 你只能使用队列的基本操作-- 也就是 push to back, peek/pop from front, size, 和 is empty 这些操作是合法的。
- 你所使用的语言也许不支持队列。 你可以使用 list 或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。
- 你可以假设所有操作都是有效的(例如, 对一个空的栈不会调用 pop 或者 top 操作)。
思路:
**后续可以尝试只用一个队列实现
代码:
typedef struct {
int front1,rear1,front2,rear2;
int data1[5000],data2[5000];
} MyStack;
MyStack* myStackCreate() {
MyStack *s=(MyStack *)malloc(sizeof(MyStack));
s->front1=s->rear1=s->front2=s->rear2=-1;
return s;
}
void myStackPush(MyStack* obj, int x) {
obj->data1[++obj->rear1]=x;
}
int myStackPop(MyStack* obj) {
int answer;
while(obj->front1!=obj->rear1-1){//除了队列1最后一个元素,其他复制到2去
obj->data2[++obj->rear2]=obj->data1[++obj->front1];
}
answer=obj->data1[++obj->front1];//读取1中剩余元素,并弹出
while(obj->front2!=obj->rear2){//2全部复制回1
obj->data1[++obj->rear1]=obj->data2[++obj->front2];
}
return answer;
}
int myStackTop(MyStack* obj) {
int answer=myStackPop(obj);
myStackPush(obj,answer);
return answer;
}
bool myStackEmpty(MyStack* obj) {
if(obj->front1==obj->rear1 && obj->front2==obj->rear2) return true;
return false;
}
void myStackFree(MyStack* obj) {
obj->front1=obj->rear1=obj->front2=obj->rear2=-1;
}
1047. 删除字符串中的所有相邻重复项
给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。
在 S 上反复执行重复项删除操作,直到无法继续删除。
在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。
示例:
- 输入:"abbaca"
- 输出:"ca"
- 解释:例如,在 "abbaca" 中,我们可以删除 "bb" 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。之后我们得到字符串 "aaca",其中又只有 "aa" 可以执行重复项删除操作,所以最后的字符串为 "ca"。
提示:
- 1 <= S.length <= 20000
- S 仅由小写英文字母组成。
**注意:
**注意在字符串操作时:改变长度后,需要补上‘\0’的位置
**判断使用栈还是队列:先入先出,后入先出;出数据 和 进入数据是否为同一端
typedef struct {
char data[99999];
int top;
}listnode;
void push(listnode * l,char e){
l->top++;
l->data[l->top]=e;
}
void pop(listnode *l){
l->top--;
}
char get(listnode *l){
return l->data[l->top];
}
bool empty(listnode*l){
if(l->top==-1) return true;
return false;
}
char* removeDuplicates(char* s) {
listnode *l=(listnode *)malloc(sizeof(listnode));
l->top=-1;
for(int i=0;i<strlen(s);i++){//遍历每个字母
if(empty(l)) push(l,s[i]); //链表空了则进栈
else if(get(l)!=s[i]) push(l,s[i]);//与上一位不同,进栈
else pop(l);//与上一位相同,上一位出栈,这一位也不能进栈
}
int i=0;
while(!empty(l)){//出栈,写入s
s[i]=get(l);
pop(l);
i++;
}
s[i]='\0';//字符串结束了
i=0;
int j=strlen(s)-1;//出栈顺序 和 要求的顺序相反,故而再转换一下
while(i<j){
char tem=s[i];
s[i]=s[j];
s[j]=tem;
i++;
j--;
}
return s;
}
优化:
看了代码随想录后发现有可以优化:直接返回栈作为字符串 :用字符串当作栈,最后直接return stack即可
char* stack = (char*)malloc(sizeof(char) * strLength + 1);
int stackTop = 0;
也可以用双指针的方法解决
20. 有效的括号
-
给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。
使用栈
**输入左括号,进栈右括号——简化对输入右括号情况的讨论
typedef struct node{
char data[11000];
int top;
}listnode;
void push(listnode *l,char e){
l->top++;
l->data[l->top]=e;
}
char pop(listnode *l){
char e;
e=l->data[l->top];
l->top--;
return e;
}
bool empty(listnode*l){
if(l->top==-1) return true;
return false;
}
bool isValid(char* s) {
listnode *l=(listnode*)malloc(sizeof(listnode));
l->top=-1;
for(int i=0;i<strlen(s);i++){
if(s[i]=='(') push(l,')');
else if (s[i]=='{') push(l,'}');
else if (s[i]=='[') push(l,']');
else {
if(empty(l) || pop(l)!=s[i]) return false;
}
}
if(empty(l)) return true;
else return false;
}