01.实现一个栈,要求实现Push、Pop、Min(返回最小值)的时间复杂度为O(1)
- 思路:我们知道取栈顶元素的时间复杂度为O(1), 如果栈顶元素就是最小的就好了,所以我们每次入栈之前, 先与栈顶元素比较
- 如果大于栈顶元素, 就把栈顶元素保存一份, 先入栈要入栈的元素, 再入栈栈顶元素
- 如果小于栈顶元素就直接入栈两次这个元素
- 同样, 出栈也要每次出两个元素
- 例如:要入栈的是5, 当前栈顶元素是3, 那么先入栈5, 再入栈3, 就保证了栈顶的元素永远是最小的
#include <stdio.h>
#include <stdlib.h>
#define DEFAULT_SZ 4
typedef char DataType;
typedef struct seqStack
{
DataType* data;
int size;
int capacity;
}seqStack;
void seqStackInit(seqStack* stack)
{
stack->data = (DataType*)malloc(sizeof(DataType) * DEFAULT_SZ);
stack->size = 0;
stack->capacity = DEFAULT_SZ;
}
void seqStackPush(seqStack* stack, DataType data)
{
if(stack == NULL)
{
return ;
}
if(stack->size == stack->capacity)
{
DataType* ptr = (DataType*)realloc(stack->data, sizeof(DataType)*stack->capacity*2 + 1);
stack->data = ptr;
}
if(data <= stack->data[stack->size-1] || stack->size == 0)
{
stack->data[stack->size] = data;
++stack->size;
stack->data[stack->size] = data;
++stack->size;
}
else
{
DataType min = stack->data[stack->size - 1];
stack->data[stack->size] = data;
++stack->size;
stack->data[stack->size] = min;
++stack->size;
}
}
void seqStackPop(seqStack* stack)
{
if(stack == NULL)
{
return ;
}
if(stack->size == 0)
{
return ;
}
--stack->size;
--stack->size;
}
DataType* seqStackMin(seqStack* stack)
{
if(stack == NULL)
{
return NULL;
}
if(stack->size == 0)
{
return NULL;
}
return &(stack->data[stack->size - 1]);
}
void seqStackPrint(seqStack* stack, char* msg)
{
printf("\n=====%s=====\n", msg);
if(stack == NULL)
{
return ;
}
if(stack->size == 0)
{
return ;
}
for(int i=stack->size - 1; i>=0; i--)
{
printf("[%c]\n", stack->data[i]);
}
printf("\n");
}
int main()
{
seqStack stack;
seqStackInit(&stack);
seqStackPush(&stack, 'a');
seqStackPush(&stack, 'b');
seqStackPush(&stack, 'c');
seqStackPush(&stack, 'd');
seqStackPrint(&stack, "入栈4次");
DataType* min;
min = seqStackMin(&stack);
printf("min expect a, actual %c\n", *min);
seqStackPop(&stack);
seqStackPop(&stack);
seqStackPrint(&stack, "出栈2次");
min = seqStackMin(&stack);
printf("min expect a, actual %c\n", *min);
seqStackPop(&stack);
seqStackPop(&stack);
seqStackPrint(&stack, "再出栈2次");
seqStackPop(&stack);
seqStackPrint(&stack, "尝试对空栈出栈");
printf("\n\n\n");
printf("\n\n\n");
printf("\n\n\n");
printf("\n\n\n");
return 0;
}

02.两个栈实现一个队列
- 思路: 两个栈, 一个用来进(input), 一个用来出(output), 入队列之后想要出队列, 就要先把input里的元素出栈, 然后入栈到output里面, 这样刚才input的栈底元素就变成了栈顶元素, 就可以先出了, 这样就达到了队列的先进先出
- 每次出完队列以后要把output里的元素出栈, 入栈回input里面, 等待下一次的入队列
#include <stdio.h>