关于leetcode232.用栈实现队列的算法解析题

题目

请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(pushpoppeekempty):

实现 MyQueue 类:

  • void push(int x) 将元素 x 推到队列的末尾
  • int pop() 从队列的开头移除并返回元素
  • int peek() 返回队列开头的元素
  • boolean empty() 如果队列为空,返回 true ;否则,返回 false

说明:

你 只能 使用标准的栈操作 —— 也就是只有 push to toppeek/pop from topsize, 和 is empty 操作是合法的。

你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。

关于leetcode232.用栈实现队列的算法解析题_第1张图片

栈的实现

#include 
#include 
#include 

#define MAX_SIZE 1000  // 栈最大容量

// 栈结构体
typedef struct {
    int data[MAX_SIZE];
    int top; // 指向栈顶元素的下标
} Stack;

// 初始化栈
void initStack(Stack* stack) {
    stack->top = -1;
}

// 判断栈是否为空
bool isEmpty(Stack* stack) {
    return stack->top == -1;
}

// 判断栈是否满
bool isFull(Stack* stack) {
    return stack->top == MAX_SIZE - 1;
}

// 入栈
void pushStack(Stack* stack, int x) {
    if (isFull(stack)) {
        printf("Stack is full!\n");
        return;
    }
    stack->data[++stack->top] = x;
}

// 出栈
int popStack(Stack* stack) {
    if (isEmpty(stack)) {
        printf("Stack is empty!\n");
        return -1;
    }
    return stack->data[stack->top--];
}

// 查看栈顶元素
int peekStack(Stack* stack) {
    if (isEmpty(stack)) {
        printf("Stack is empty!\n");
        return -1;
    }
    return stack->data[stack->top];
}

用栈实现队列

// 队列结构体
typedef struct {
    Stack inStack;
    Stack outStack;
} MyQueue;

// 初始化队列
MyQueue* myQueueCreate() {
    MyQueue* queue = (MyQueue*)malloc(sizeof(MyQueue));
    initStack(&queue->inStack);
    initStack(&queue->outStack);
    return queue;
}

// 辅助函数:把inStack的元素全部倒入outStack
void move(MyQueue* queue) {
    if (isEmpty(&queue->outStack)) {
        while (!isEmpty(&queue->inStack)) {
            int val = popStack(&queue->inStack);
            pushStack(&queue->outStack, val);
        }
    }
}

// 将元素推到队列末尾
void myQueuePush(MyQueue* queue, int x) {
    pushStack(&queue->inStack, x);
}

// 移除并返回队列开头元素
int myQueuePop(MyQueue* queue) {
    move(queue);
    return popStack(&queue->outStack);
}

// 返回队列开头元素
int myQueuePeek(MyQueue* queue) {
    move(queue);
    return peekStack(&queue->outStack);
}

// 判断队列是否为空
bool myQueueEmpty(MyQueue* queue) {
    return isEmpty(&queue->inStack) && isEmpty(&queue->outStack);
}

// 释放队列资源
void myQueueFree(MyQueue* queue) {
    free(queue);
}

总结

两个栈,一个负责输入(inStack),一个负责输出(outStack)。

只有在outStack为空时,才把inStack元素搬过去,保证顺序。

栈的基本操作只有 push、pop、peek、empty,符合题目要求。

push() 时间复杂度是 O(1),pop()peek() 最坏是 O(n),但均摊下来是 O(1)。

你可能感兴趣的:(算法)