问题1:实现一个栈,要求实现入栈(Push)出栈(Pop)返回最小值(Min),要求时间复杂度为0(1)
问题分析:由前面所写的栈的基本操作,我们可知,入栈和出栈的时间复杂度都为0(1),故只需在返回最小值时算法时,满足时间复杂度为0(1)即可
思路:以空间换时间,借助双栈(具体过程看下图)
具体代码:
//初始化
void MinStackInit(MinStack* mins)
{
assert(mins);
mins->_minst = NULL;
mins->_st = NULL;
mins->_minst_top = 0;
mins->_st_op = 0;
mins->_minst_end = 0;
mins->_st_end = 0;
}
//入栈
void MinStackPush(MinStack* mins, DataType x)
{
assert(mins);
if (mins->_st_end == mins->_st_end || mins->_st_op==mins->_st_end)
{
size_t size = mins->_st_op > 0 ? mins->_st_op * 2 : 3;
mins->_st = (DataType*)realloc(mins->_st, sizeof(DataType)*size);
mins->_minst = (DataType*)realloc(mins->_minst, sizeof(DataType)*size);
assert(mins->_st);
assert(mins->_minst);
mins->_minst_end = size;
mins->_st_end = size;
}
mins->_st[mins->_st_op] = x;
mins->_st_op++;
if (mins->_minst_top == 0 || x <= mins->_st[mins->_minst_top - 1])
{
//minst入栈条件
mins->_minst[mins->_minst_top] = x;
mins->_minst_top++;
}
}
//出栈
void MinStackPop(MinStack* mins)
{
assert(mins);
if (mins->_st_op == 0)
{
printf("Stack is empty\n");
return;
}
if (mins->_minst[mins->_minst_top - 1] == mins->_st[mins->_st_op - 1])
{
//出栈条件
--mins->_minst_top;
}
-- mins->_st_op;
}
DataType GetMin(MinStack* mins)
{
assert(mins);
return mins->_minst[mins->_minst_top - 1];
}
void TestMinStack()
{
MinStack mins;
MinStackInit(&mins);
MinStackPush(&mins, 2);
MinStackPush(&mins, 1);
MinStackPush(&mins, 3);
MinStackPush(&mins, 0);
MinStackPush(&mins, 0);
MinStackPush(&mins, 2);
printf("min:%d\n", GetMin(&mins));
MinStackPop(&mins);
printf("min:%d\n", GetMin(&mins));
MinStackPop(&mins);
printf("min:%d\n", GetMin(&mins));
MinStackPop(&mins);
printf("min:%d\n", GetMin(&mins));
MinStackPop(&mins);
printf("min:%d\n", GetMin(&mins));
MinStackPop(&mins);
printf("min:%d\n", GetMin(&mins));
MinStackPop(&mins);
printf("min:%d\n", GetMin(&mins));
MinStackPop(&mins);
}
问题2:元素入栈,入栈的合法性。如入栈的序列(1,2,3,4,5),出栈序列为(4,5,3,2,1)
思路:将原序列入栈,每入栈一个数据,将其与验证序列进行比较,如果相同,验证序列向后比较,并将其刚入栈的数据进行出栈操作,不同则继续将原序列入栈(这里只画了符合入栈出栈顺序的图,可以按照这种方式画一下不符合的图)
具体代码:
int IsInvalidStackOrder(DataType* pushOrder, size_t pushSize,
DataType* popOrder, size_t popSize)
{
assert(pushOrder);
assert(popOrder);
assert(popSize == popSize);
Stack st;
StackInit(&st);
size_t push = 0;
size_t pop = 0;
while (push < pushSize)
{
StackPush(&st, pushOrder[push++]);
while (StackEmpty(&st) != 0)
{
if (popOrder[pop] == StackTop(&st))
{
//出栈条件
++pop;
StackPop(&st);
}
else
{
break;
}
}
}
if (pop == push)
{
return 1;
}
else
{
return 0;
}
}
void TestIsInvalidStackOrder()
{
DataType pushorder[] = { 1, 2, 3, 4, 5 };
DataType poporder[] = { 4, 5, 3, 1, 2 };
printf("%d ", IsInvalidStackOrder(pushorder, sizeof(pushorder) / sizeof(DataType), poporder, sizeof(poporder) / sizeof(DataType)));
}