经典题~
1.用栈的方式,实现一个队列的结构
思路
先想性质:栈是先进后出,队列是先进先出。
那用两个栈来回倒腾,是不是就可以实现队列的模式了
分两个栈,一个help栈,一个data栈。
data栈一开始进的数据是 1 2 3 4 5
输出的数据是 5 4 3 2 1
但是想要队列的结构,所以我们实际想输出的是1-2-3-4-5
那就把data栈里的data放进help栈里,再输出
pay attention!
还是有一些小细节
一旦data开始导数据,必须导空
一旦help开始倒数据,也必须倒空
不然数据就会乱掉...
代码
struct Queue{ // 队列,由data数组和help数组组成
struct Stack data;
struct Stack help;
};
void enqueue(struct Queue* queue, int data){
push(&queue->data, data); // 这边的细节在于要写 &queue->data 因为上面是指针格式
}
int dequeue(struct Queue* queue){
if(queue ==NULL){
return;
}
while(queue->data->top != NULL){ //一旦开始倒,就全部倒空到help栈里去
push(&queue->help, pop(&queue->data));
}
int val = pop(&queue->help); //弹help的栈顶元素
while(queue->help->top !=NULL){ // 此时data栈为空,需要把队列恢复原本的模样,方便下一次弹出操作
push(&queue->data, pop(&queue->help));
}
return val;
}
2.用队列方式,实现一个栈的结构
思路
仍旧是先想性质。 队列是先进先出,栈是先进后出....
现在有两个队列
A 1 2 3 4 5
B NULL
我要用5 4 3 2 1的次序输出,怎么办?
先把A中的1 2 3 4 挪到B数组中,然后输出A剩下的!
A 5
B 1 2 3 4
5输出掉之后 ,A变成空,再输出4
A 1 2 3
B 4 ...............依此类推
代码
struct Stack{
struct Queue* queue1;
struct Queue* queue2;
};
void push(struct Stack* stack, int data){
enqueue(&stack->queue1, data);
}
int pop(struct Stack *s) {
//将主队列中的元素全部出队并入队到辅助队列中,只留下最后一个元素
while (!isQueueEmpty(&s->queue1)) { // 不愧是chatgpt写的...思路好奇妙
int value = dequeue(&s->queue1); //先用value逐个记录值,当记录完最后一个的时候
// 此时queue为空,返回这最后一个值
if (!isQueueEmpty(&s->queue1)) {
enqueue(&s->queue2, value);
} else {
//最后一个元素出队
return value;
}
}
//如果主队列为空,则辅助队列中的元素即为栈中元素
while (!isQueueEmpty(&s->queue2)) { //如果辅助队列不为空,就再倒回主队列
int value = dequeue(&s->queue2);
enqueue(&s->queue1, value);
}
return -1;
}
3.输出栈中的最小值,且要求时间复杂度为O(1)
输出最小值很容易...
比如我把栈里的数字依次pop出来,之后再随便做个排序
思路很简单,但是不符合题目要求:时间复杂度O(1)
思路
那么这样的话思路是怎么样呢?
依旧是那个思路:辅助栈
比如这样一组数 3 4 2 7 1 0 (<-----------次序是这样,3是栈顶元素)
一开始他们在data栈中
这时候我们设置一个min栈,依次弹出data栈中的数据并放进min栈中
但是有一个小思路,就是 假设后面进这个数字比前面这个数字大的话,就不入栈,让值等于上一个
for example
3最先弹出到data栈中,下一个弹4
比较后发现4>3,于是乎 本来应该是 4 3 的min栈,现在成3 3
下一次弹2, min栈就变成2 3 3....
coding!
可以看到,这个方式没有经过遍历,时间复杂度为O(1)
代码
int minStack(struct Stack* stack){
struct Stack* data = stack;
struct Stack* min = NULL;
while(data->top != NULL){ //只要data栈不是空的,就继续往下
int val = pop(&data);
push(&min, val); // 第一次先把最初的栈顶元素压进去
if(data->top->value <= min->top->value){
int val2 = pop(&data);
push(&min, val2);
}
else{
data->top->value = min->top->value;
int val2 = pop(&data);
push(&min, val2);
}
}
return min->top->value;
}