1.用两个栈实现队列
用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )
示例 1:
输入:
["CQueue","appendTail","deleteHead","deleteHead","deleteHead"]
[[],[3],[],[],[]]
输出:[null,null,3,-1,-1]
输入:
["CQueue","deleteHead","appendTail","appendTail","deleteHead","deleteHead"]
[[],[],[5],[2],[],[]]
输出:[null,-1,null,null,5,2]
思路分析:
第一次看到这道题目的时候,我第一次看算法题,我有些懵,题目是利用两个栈实现一个队列
我的思路是先去了解知识点,但是了解知识点后又有点懵,主要是对它的测试集格式有些懵,没有搞懂它输入输出想干什么
思路分解;
- 使用两个栈来实现队列的功能。
- 支持两个操作:
appendTail(x)
:将元素x
添加到队尾。deleteHead()
:删除队首的元素并返回删除的元素值,如果队列为空则返回 -1。
根据题目的要求,可以利用两个栈来模拟队列的入队和出队操作。其中一个栈(称为入队栈)用于将新元素添加到队列的尾部,另一个栈(称为出队栈)用于删除队列的头部元素。
具体的思路如下:
- 初始化两个空栈,一个用于入队(stack1),一个用于出队(stack2)。
- 对于
appendTail(x)
操作,直接将元素x
入栈stack1
。 - 对于
deleteHead()
操作:- 如果
stack2
不为空,直接从stack2
出栈并返回栈顶元素。 - 如果
stack2
为空,且stack1
也为空,说明队列为空,返回 -1。 - 如果
stack2
为空,但stack1
不为空,将stack1
中的所有元素出栈并入栈到stack2
,然后从stack2
出栈并返回栈顶元素。
- 如果
class CQueue(object):
def __init__(self):
self.stack1=[]
self.stack2=[]
def appendTail(self, value):
"""
:type value: int
:rtype: None
"""
self.stack1.append(value)
def deleteHead(self):
"""
:rtype: int
"""
if len(self.stack2) !=0:
return self.stack2.pop()
elif len(self.stack1)==0 and len(self.stack2) ==0:
return -1
else:
while len(self.stack1) != 0:
self.stack2.append(self.stack1.pop())
return self.stack2.pop()
if __name__ == '__main__':
pass
另一种思路:用列表做栈,每次添加的时候,直接添加在头部,然后删除的时候,直接pop删除尾部,即可形成队列,即,用一个栈即可实现队列
class CQueue(object):
def __init__(self):
self.stack1=[]
self.stack2=[]
def appendTail(self, value):
"""
:type value: int
:rtype: None
"""
self.stack1.append(value)
def deleteHead(self):
"""
:rtype: int
"""
if len(self.stack1) == 0:
return -1
return self.stack1.pop(0)
if __name__ == '__main__':
pass
相关知识点:
1.栈:具有先入后出的特点的抽象数据结构,可使用数组或链表实现。对于数组的我比较好理解,但是对于链表实现,不是很理解
链表是一种线性数据结构,由一个个节点组成,每个节点包含一个数据元素和一个指向下一个节点的指针。栈是一种先进后出(Last In First Out,LIFO)的数据结构,只允许在栈顶进行插入和删除操作。
python版本
#使用列表表示
stack = [] # Python 可将列表作为栈使用
stack.append(1) # 元素 1 入栈
stack.append(2) # 元素 2 入栈
stack.pop() # 出栈 -> 元素 2
stack.pop() # 出栈 -> 元素 1
#使用链表表示
# 定义链表节点
class Node:
def __init__(self, data):
self.data = data
self.next = None
# 定义栈数据结构
class Stack:
def __init__(self):
self.top = None
# 判断栈是否为空
def is_empty(self):
return self.top is None
# 入栈
def push(self, data):
new_node = Node(data)
if self.is_empty():
self.top = new_node
else:
new_node.next = self.top
self.top = new_node
# 出栈
def pop(self):
if self.is_empty():
raise Exception("Stack is empty.")
popped_node = self.top
self.top = popped_node.next
popped_node.next = None
return popped_node.data
# 获取栈顶元素
def peek(self):
if self.is_empty():
raise Exception("Stack is empty.")
return self.top.data
# 测试代码
stack = Stack()
stack.push(1)
stack.push(2)
stack.push(3)
print(stack.pop()) # 输出:3
print(stack.peek()) # 输出:2
print(stack.is_empty()) # 输出:False
C版本
stack<int> stk;
stk.push(1); // 元素 1 入栈
stk.push(2); // 元素 2 入栈
stk.pop(); // 出栈 -> 元素 2
stk.pop(); // 出栈 -> 元素 1
//用链表实现
#include <stdio.h>
#include <stdlib.h>
// 定义链表节点
struct Node {
int data;
struct Node* next;
};
// 定义栈数据结构
struct Stack {
struct Node* top;
};
// 初始化栈
void initStack(struct Stack* stack) {
stack->top = NULL;
}
// 判断栈是否为空
int isEmpty(struct Stack* stack) {
return stack->top == NULL;
}
// 入栈
void push(struct Stack* stack, int data) {
struct Node* newNode = (struct Node*) malloc(sizeof(struct Node));
newNode->data = data;
newNode->next = stack->top;
stack->top = newNode;
}
// 出栈
int pop(struct Stack* stack) {
if (isEmpty(stack)) {
printf("Stack is empty.\n");
return -1;
}
struct Node* poppedNode = stack->top;
int data = poppedNode->data;
stack->top = poppedNode->next;
free(poppedNode);
return data;
}
// 获取栈顶元素
int peek(struct Stack* stack) {
if (isEmpty(stack)) {
printf("Stack is empty.\n");
return -1;
}
return stack->top->data;
}
// 测试代码
int main() {
struct Stack stack;
initStack(&stack);
push(&stack, 1);
push(&stack, 2);
push(&stack, 3);
printf("%d\n", pop(&stack)); // 输出:3
printf("%d\n", peek(&stack)); // 输出:2
printf("%d\n", isEmpty(&stack)); // 输出:0(非空)
return 0;
}
2.题目给的样式
class CQueue(object):
def __init__(self):
def appendTail(self, value):
"""
:type value: int
:rtype: None
"""
def deleteHead(self):
"""
:rtype: int
"""
# Your CQueue object will be instantiated and called as such:
# obj = CQueue()
# obj.appendTail(value)
# param_2 = obj.deleteHead()