实现一个栈,要求实现Push(入栈)、Pop(出栈)、Min(取栈中最小值)、Max(取栈中最大值)的时间复杂度为O(1)。

栈刷题——求栈中的最小值和最大值,时间复杂度为O(1)

题目描述:

实现一个栈,要求实现Push(入栈)、Pop(出栈)、Min(取栈中最小值)、Max(取栈中最大值)的时间复杂度为O(1)。

解题思路:

使用三个栈来解决。一个正常栈,一个最小值栈,一个最大值栈

每个元素进栈的时候,

除了第一个元素三个栈都进入的

比较这个元素和最小栈的栈顶的元素和最大栈的栈顶的元素的大小:

如果这个元素比最小栈栈顶的元素小,那么这个元素进入最小栈和正常栈;

如果这个元素比最大栈栈顶的元素大,那么这个元素进入最大栈和正常栈;

如果这个元素即比最大栈栈顶的元素小又比最小栈栈顶的元素大,那么这个元素只进入正常栈;

image-20211008140315949 image-20211008145723361

代码解决:

栈的结构设计

三个栈组合栈

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
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值