面试题1:实现一个栈,要求实现Push(出栈)、Pop(入栈)、Min(返回最小值)的时间复杂度为O(1)
解题思路:我们可以利用一个辅助栈(MinStack),用来存储最小值,在最开始的情况下两个栈同时入,当继续入栈时判断该元素是否小于或等于上一个入栈元素,若小于或等于则同时入两个栈,否则只入Stack,当出栈时用MinStack的栈顶元素和Stack栈顶元素比较,若相等则两个栈同时出栈,最后Stack的最小值就为MinStack的栈顶元素
MinStackNum.h
#pragma once
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <assert.h>
#include <malloc.h>
#include <stdlib.h>
#include "Stack.h"
typedef int DataType;
typedef struct Stack
{
DataType *_a;
int _top;
int _capacity;
}Stack;
typedef struct StackMin
{
Stack s1;
Stack s2;
}StackMin;
void StackInit(Stack *p);
void StackDestroy(Stack *p);
void StackPush(Stack *p, DataType x);
void StackPop(Stack *p);
DataType StackTop(Stack *p);
int StackEmpty(Stack *p);
int StackSize(Stack *p);
void StackMinInit(StackMin *ps);
void StackMinDestroy(StackMin *ps);
void StackMinPush(StackMin *ps,DataType x);
void StackMinPop(StackMin *ps);
int StackMinNum(StackMin *ps);
MinStackNum.c
#include "StackM.h"
#include "Stack.h"
void StackMinInit(StackMin *ps)
{
StackInit(&ps->s1);
StackInit(&ps->s2);
}
void StackMinDestroy(StackMin *ps)
{
assert(ps);
StackDestroy(&ps->s1);
StackDestroy(&ps->s2);
}
void StackMinPush(StackMin *ps,DataType x)
{
assert(ps);
StackPush(&ps->s1, x);
if (StackSize(&ps->s1) == 1)
{
StackPush(&ps->s2, StackTop(&ps->s1));
}
else
{
if (StackTop(&ps->s1) <= StackTop(&ps->s2))
StackPush(&ps->s2, StackTop(&ps->s1));
}
}
void StackMinPop(StackMin *ps)
{
assert(ps);
if (StackTop(&ps->s1) >= StackTop(&ps->s2))
{
StackPop(&ps->s1);
StackPop(&ps->s2);
}
else
StackPop(&ps->s1);
}
DataType StackMinNum(StackMin *ps)
{
assert(ps);
return StackTop(&ps->s2);
}
test.c
#include "Stack.h"
#include "StackM.h"
int main()
{
StackMin ps;
StackMinInit(&ps);
StackMinPush(&ps, 5);
StackMinPush(&ps, 4);
StackMinPush(&ps, 2);
StackMinPush(&ps, 3);
StackMinPush(&ps, 1);
StackMinPop(&ps);
printf("栈的最小值为: %d\n", StackMinNum(&ps););
StackMinDestroy(&ps);
system("pause");
return 0;
}
使用两个栈实现一个队列
解题思路:利用栈的先入后出特性,使用两个栈,一个栈s1负责入,一个栈s2负责出,这样s2的Top就相当于队列中的Front
QueueByTwoStack.h
#pragma once
#include <stdio.h>
#include <malloc.h>
#include <assert.h>
#include <stdlib.h>
typedef int DataType;
typedef struct Stack
{
DataType* _a;
int _top; // 栈顶
int _capacity; // 容量
}Stack;
// 两个栈实现一个队列
typedef struct QueueByTwoStack
{
Stack s1;
Stack s2;
}QueueByTwoStack;
void QueueInit(QueueByTwoStack* pq);
void QueueDestory(QueueByTwoStack* pq);
void QueuePush(QueueByTwoStack* pq, DataType x);
void QueuePop(QueueByTwoStack* pq);
DataType QueueFront(QueueByTwoStack* pq);
int QueueEmpty(QueueByTwoStack* pq);
int QueueSize(QueueByTwoStack* pq);
void TestQueue();
QueueByTwoStack.c
#include"QueueByTwoStack.h"
void QueueInit(QueueByTwoStack * pq)
{
assert(pq);
StackInit(&pq->s1);
StackInit(&pq->s2);
}
void QueueDestory(QueueByTwoStack* pq)
{
assert(pq);
StackDestory(&pq->s1);
StackDestory(&pq->s2);
}
void QueuePush(QueueByTwoStack* pq, DataType x)
{
assert(pq);
StackPush(&pq->s1, x);
}
void QueuePop(QueueByTwoStack* pq)
{
//判断s2是否为空
if (StackEmpty(&pq->s2))
{
StackPop(&pq->s2);
}
//若s1不为空则将s1的Top入到s2中,相当于将s1中的数据又倒了回来
//这样就能保证s2的Top数据相当于队头数据
else if (StackEmpty(&pq->s1))
{
while (StackEmpty(&pq->s1))
{
StackPush(&pq->s2, StackTop(&pq->s1));
StackPop(&pq->s1);
}
}
}
DataType QueueFront(QueueByTwoStack* pq)
{
assert(pq);
return StackTop(&pq->s2);
}
int QueueEmpty(QueueByTwoStack* pq)
{
assert(pq);
return StackEmpty(&pq->s1) || StackEmpty(&pq->s2);
}
int QueueSize(QueueByTwoStack* pq)
{
assert(pq);
return StackSize(&pq->s1) + StackSize(&pq->s2);
}
void TestQueue()
{
}
test.c
#include"QueueByTwoStack.h"
int main()
{
Stack s;
int i = 0;
StackInit(&s);
StackPush(&s, 1);
StackPush(&s, 2);
StackPush(&s, 3);
StackPush(&s, 4);
StackPush(&s, 5);
for (i = 0; i < 5; i++)
{
printf("%d ", StackTop(&s));
StackPop(&s);
}
printf("\n");
StackDestory(&s);
system("pause");
return 0;
}
使用两个队列实现一个栈
解题思路:入队时,直接压入q1中, 出队时,判断若q2是否为空,如果q2为空,则将q1中的前n-1个元素倒入q2中,然后再Pop掉q1中的最后一个元素. 否则q1空,则将q2中的前n-1元素倒入q1中,然后再Pop掉q2中的最后一个元素, 始终保持栈顶元素为q1或q2中非空队列的队尾元素为栈顶元素;
StackByTwoQueue.h
#pragma once
#include <stdio.h>
#include <malloc.h>
#include <assert.h>
#include <stdlib.h>
typedef int DataType;
typedef struct QueueNode
{
struct QueueNode* _next;
DataType _data;
}QueueNode;
typedef struct Queue
{
QueueNode* _front; // 队头
QueueNode* _back; // 队尾
}Queue;
typedef struct Stack
{
Queue q1;
Queue q2;
}Stack;
void StackInit(Stack* ps);
void StackDestory(Stack* ps);
void StackPush(Stack* ps, DataType x);
void StackPop(Stack* ps);
DataType StackTop(Stack* ps);
int StackEmpty(Stack* ps);
int StackSize(Stack* ps);
void TestStack();
StackByTwoQueue.c
#include "StackByTwoQueue.h"
void StackInit(Stack* ps)
{
assert(&ps->q1);
QueueInit(&ps->q1);
QueueInit(&ps->q2);
}
void StackDestory(Stack* ps)
{
assert(ps);
QueueDestory(&ps->q1);
QueueDestory(&ps->q2);
}
void StackPush(Stack* ps, DataType x)
{
assert(ps);
QueuePush(&ps->q1, x);
}
void StackPop(Stack* ps)
{
assert(ps);
assert(&ps->q1 || &ps->q2);
//判断q1是否为空
if (QueueEmpty(&ps->q1))
{
while (QueueSize(&ps->q1) != 1)
{
QueuePush(&ps->q2, QueueFront(&ps->q1));
QueuePop(&ps->q1);
}
QueuePop(&ps->q1);
}
else
{
while (QueueSize(&ps->q2) != 1)
{
QueuePush(&ps->q1, QueueFront(&ps->q2));
QueuePop(&ps->q2);
}
QueuePop(&ps->q2);
}
}
DataType StackTop(Stack* ps)
{
assert(ps);
if (QueueEmpty(&ps->q1))
return (&ps->q1)->_back->_data;
else if (QueueEmpty(&ps->q2))
return (&ps->q2)->_back->_data;
else perror("Top Empty");
}
int StackEmpty(Stack* ps)
{
assert(ps);
return (QueueEmpty(&ps->q1) || QueueEmpty(&ps->q2));
}
int StackSize(Stack* ps)
{
assert(ps);
return (QueueSize(&ps->q1) + QueueSize(&ps->q2));
}
void TestStack()
test.c
#include "StackByTwoQueue.h"
int main()
{
Stack s;
int i = 0;
StackInit(&s);
StackPush(&s, 1);
StackPush(&s, 2);
StackPush(&s, 3);
StackPush(&s, 4);
StackPush(&s, 5);
while (StackEmpty(&s))
{
printf("%d ", StackTop(&s));
StackPop(&s);
}
printf("\n");
StackDestory(&s);
system("pause");
return 0;
}
元素出栈、入栈顺序的合法性。如入栈的序列(1,2,3,4,5),出栈序列为
(4,5,3,2,1)
解题思路 : 我们可以将数组1的元素入栈 ,每入一个元素, 就将栈顶元素和数组2中的数据比较, 如果相同则出栈,然后在用栈顶元素和数组2的下一个元素比较, 如果相等继续出栈, 直到不相等为止, 如果不相同数组1就继续入栈, 当数组1全部入栈时, 循环结束, 然后只需要判断栈是否为空, 若栈为空则合法, 否则不合法.
int JudgeStack(int arv[], int arg[], int length1, int length2)
{
Stack ps;
int len1 = 0;
int len2 = 0;
StackInit(&ps);
if ((length1 != length2) || arv == NULL || arg == NULL)
{
return -1;
}
while (len1 < length1)
{
StackPush(&ps, arv[len1]);
len1++;
//当数组2元素等于栈顶元素时,直到不相等或者数组2无元素时
while ((len2 < length2) &&
(arg[len2] == StackTop(&ps)))
{
StackPop(&ps);
len2++;
}
}
//空则合法
if (StackEmpty(&ps))
{
StackDestroy(&ps);
return 0;
}
//非空不合法
else
{
StackDestroy(&ps);
return 1;
}
}