栈刷题——求栈中的最小值和最大值,时间复杂度为O(1)
题目描述:
实现一个栈,要求实现Push(入栈)、Pop(出栈)、Min(取栈中最小值)、Max(取栈中最大值)的时间复杂度为O(1)。
解题思路:
使用三个栈来解决。一个正常栈,一个最小值栈,一个最大值栈
每个元素进栈的时候,
除了第一个元素三个栈都进入的
比较这个元素和最小栈的栈顶的元素和最大栈的栈顶的元素的大小:
如果这个元素比最小栈栈顶的元素小,那么这个元素进入最小栈和正常栈;
如果这个元素比最大栈栈顶的元素大,那么这个元素进入最大栈和正常栈;
如果这个元素即比最大栈栈顶的元素小又比最小栈栈顶的元素大,那么这个元素只进入正常栈;
![image-20211008140315949](https://gitee.com/luoxiangyu/picture-bed/raw/master/202110081507871.png)
![image-20211008145723361](https://gitee.com/luoxiangyu/picture-bed/raw/master/202110081507876.png)
代码解决:
栈的结构设计
三个栈组合栈
struct StackM
{
STDataType* a;
int top;//栈顶
int capacity;//容量
};
struct StackS
{
STDataType* a;
int top;//栈顶
int capacity;//容量
};
struct StackL
{
STDataType* a;
int top;//栈顶
int capacity;//容量
};
struct Stack
{
StackM m1;
StackS s1;
StackL l1;
};
初始化栈
Stack st1 = { 0 };
StackInit(&st1);
void StackInit(Stack* pst)
{
pst->m1.a = (STDataType*)malloc(sizeof(STDataType) * 4);
pst->m1.capacity = 4;
pst->m1.top = -1;
pst->s1.a = (STDataType*)malloc(sizeof(STDataType) * 4);
pst->s1.capacity = 4;
pst->s1.top = -1;
pst->l1.a = (STDataType*)malloc(sizeof(STDataType) * 4);
pst->l1.capacity = 4;
pst->l1.top = -1;
}
压栈
void StackPush(Stack* pst, STDataType x)
{
//如果满了的话
if (pst->m1.top == pst->m1.capacity-1)
{
STDataType* cur = (STDataType*)realloc(pst->m1.a, sizeof(STDataType) * pst->m1.capacity * 2);
if (cur != NULL)
{
pst->m1.a = cur;
pst->m1.capacity *= 2;
}
}
if (pst->s1.top == pst->s1.capacity-1)
{
STDataType* cur = (STDataType*)realloc(pst->s1.a, sizeof(STDataType) * pst->s1.capacity * 2);
if (cur != NULL)
{
pst->s1.a = cur;
pst->s1.capacity *= 2;
}
}
if (pst->l1.top == pst->l1.capacity-1)
{
STDataType* cur = (STDataType*)realloc(pst->l1.a, sizeof(STDataType) * pst->l1.capacity * 2);
if (cur != NULL)
{
pst->l1.a = cur;
pst->l1.capacity *= 2;
}
}
//插入元素
//第一个进行插入的元素,三个都进
if (pst->l1.top == -1 && pst->m1.top == -1 && pst->s1.top == -1)
{
pst->l1.a[++(pst->l1.top)] = pst->m1.a[++(pst->m1.top)] = pst->s1.a[++(pst->s1.top)] = x;
}
//非第一次插入的元素,如果比l1中的大,进入l1和m1
else if (x >= pst->l1.a[pst->l1.top])
{
pst->m1.a[++(pst->m1.top)]=pst->l1.a[++(pst->l1.top)] = x;
}
//比小的还小
else if(x <= pst->s1.a[pst->s1.top])
{
pst->m1.a[++(pst->m1.top)] = pst->s1.a[++(pst->s1.top)] = x;
}
//即不比大的大,也不比小的小
else
{
pst->m1.a[++(pst->m1.top)] = x;
}
}
出栈
void StackPop(Stack* pst)
{
assert(pst->m1.top!=-1);
if (pst->m1.a[pst->m1.top] == pst->s1.a[pst->s1.top])
{
pst->m1.top--;
pst->s1.top--;
}
if (pst->m1.a[pst->m1.top] == pst->l1.a[pst->l1.top])
{
pst->m1.top--;
pst->l1.top--;
}
}
得到最大值
最大栈栈顶的就是最大值
STDataType StackMax(StackL* pl1)
{
assert(pl1->top!=-1);
return pl1->a[pl1->top];
}
得到最小值
最小栈栈顶的就是最小值
STDataType StackMin(StackS* ps1)
{
assert(ps1->top != -1);
return ps1->a[ps1->top];
}
全部代码
struct StackM
{
STDataType* a;
int top;//栈顶
int capacity;//容量
};
struct StackS
{
STDataType* a;
int top;//栈顶
int capacity;//容量
};
struct StackL
{
STDataType* a;
int top;//栈顶
int capacity;//容量
};
struct Stack
{
StackM m1;
StackS s1;
StackL l1;
};
void StackInit(Stack* pst)
{
pst->m1.a = (STDataType*)malloc(sizeof(STDataType) * 4);
pst->m1.capacity = 4;
pst->m1.top = -1;
pst->s1.a = (STDataType*)malloc(sizeof(STDataType) * 4);
pst->s1.capacity = 4;
pst->s1.top = -1;
pst->l1.a = (STDataType*)malloc(sizeof(STDataType) * 4);
pst->l1.capacity = 4;
pst->l1.top = -1;
}
void StackPush(Stack* pst, STDataType x)
{
//如果满了的话
if (pst->m1.top == pst->m1.capacity-1)
{
STDataType* cur = (STDataType*)realloc(pst->m1.a, sizeof(STDataType) * pst->m1.capacity * 2);
if (cur != NULL)
{
pst->m1.a = cur;
pst->m1.capacity *= 2;
}
}
if (pst->s1.top == pst->s1.capacity-1)
{
STDataType* cur = (STDataType*)realloc(pst->s1.a, sizeof(STDataType) * pst->s1.capacity * 2);
if (cur != NULL)
{
pst->s1.a = cur;
pst->s1.capacity *= 2;
}
}
if (pst->l1.top == pst->l1.capacity-1)
{
STDataType* cur = (STDataType*)realloc(pst->l1.a, sizeof(STDataType) * pst->l1.capacity * 2);
if (cur != NULL)
{
pst->l1.a = cur;
pst->l1.capacity *= 2;
}
}
//插入元素
//第一个进行插入的元素,三个都进
if (pst->l1.top == -1 && pst->m1.top == -1 && pst->s1.top == -1)
{
pst->l1.a[++(pst->l1.top)] = pst->m1.a[++(pst->m1.top)] = pst->s1.a[++(pst->s1.top)] = x;
}
//非第一次插入的元素,如果比l1中的大,进入l1和m1
else if (x >= pst->l1.a[pst->l1.top])
{
pst->m1.a[++(pst->m1.top)]=pst->l1.a[++(pst->l1.top)] = x;
}
//比小的还小
else if(x <= pst->s1.a[pst->s1.top])
{
pst->m1.a[++(pst->m1.top)] = pst->s1.a[++(pst->s1.top)] = x;
}
//即不比大的大,也不比小的小
else
{
pst->m1.a[++(pst->m1.top)] = x;
}
}
void StackPop(Stack* pst)
{
assert(pst->m1.top!=-1);
if (pst->m1.a[pst->m1.top] == pst->s1.a[pst->s1.top])
{
pst->m1.top--;
pst->s1.top--;
}
if (pst->m1.a[pst->m1.top] == pst->l1.a[pst->l1.top])
{
pst->m1.top--;
pst->l1.top--;
}
}
STDataType StackMax(StackL* pl1)
{
assert(pl1->top!=-1);
return pl1->a[pl1->top];
}
STDataType StackMin(StackS* ps1)
{
assert(ps1->top != -1);
return ps1->a[ps1->top];
}
int main()
{
Stack st1 = { 0 };
StackInit(&st1);
StackPush(&st1, 5);
StackPush(&st1, 2);
StackPush(&st1, 3);
StackPush(&st1, 7);
//StackPop(&st1);
int max=StackMax(&st1.l1);
int min=StackMin(&st1.s1);
return 0;
}
效果展示:
![image-20211008150719652](https://gitee.com/luoxiangyu/picture-bed/raw/master/202110081507878.png)