题目
用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )
示例 1:
输入:
[“CQueue”,“appendTail”,“deleteHead”,“deleteHead”]
[[],[3],[],[]]
输出:[null,null,3,-1]
示例 2:
输入:
[“CQueue”,“deleteHead”,“appendTail”,“appendTail”,“deleteHead”,“deleteHead”]
[[],[],[5],[2],[],[]]
输出:[null,-1,null,null,5,2]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof
分析
两个栈模拟一个队列,队列是先进先出,而栈是先进后出。我们只需要两个栈倒一手,即进栈A,然后在弹出到B。比如栈A分别进入1, 2, 3,在栈顶的是3。那么倒一手到栈B,将分别把3, 2, 1进栈,此时栈B的栈顶是1。此时如果要出队,就从B上出栈,这时候出的是1。是不是就实现了队列先进先出了呢?
此题有个问题是,go语言并没有提供栈这种内部实现,所以我们要采用slice来模拟栈,入栈就append,出栈就取末尾,实现先进后出,或者叫后进先出。
解法
type CQueue struct {
s1 Stack
s2 Stack
}
func Constructor() CQueue {
return CQueue{}
}
func (this *CQueue) AppendTail(value int) {
this.s1.Push(value)
}
func (this *CQueue) DeleteHead() int {
// 如果s2不为空,那么就直接pop就好了。
// 把s1的都push到s2,然后从s2里pop出来。
if this.s2.Size() == 0 && this.s1.Size() > 0{
for this.s1.Size() > 0 {
this.s2.Push(this.s1.Pop())
}
}
if this.s2.Size() > 0 {
return this.s2.Pop()
} else {
return -1
}
}
type Stack []int
func(s *Stack) Size() int {
return len(*s)
}
// 以下栈的定义来自leetcode 题解中的一篇,其实就是用slice模拟栈,具体是哪位仁兄的忘记了。
func(s *Stack) Push(value int) {
*s = append(*s, value)
}
func(s *Stack) Pop() int {
n := len(*s)
res := (*s)[n - 1]
*s = (*s)[:n - 1]
return res
}
/**
* Your CQueue object will be instantiated and called as such:
* obj := Constructor();
* obj.AppendTail(value);
* param_2 := obj.DeleteHead();
*/