Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
一、题目描述
用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )
输入:
["CQueue","appendTail","deleteHead","deleteHead"][[],[3],[],[]]输出:[null,null,3,-1]
二、思路分析
- 栈是先进后出,队列是先进先出,用两个栈实现队列以及两个操作尾部增加和头部删除。
- 第一次可以考虑用
go中的数组当做栈,go没有提供显式的栈数据结构,但是切片操作非常容易模拟栈,使用nums :=append(nums,val),可以数据入栈,数据出栈则是nums = nums[:len(nums)-1]的切片操作。 - 队列的添加操作,直接将元素加入1号栈即可,删除操作首先判断s2栈是否为空,如果为空就将栈1的数据全部入栈2,然后栈2元素出栈一个并返回。
- go中的双向链表
*list.List支持后面插入及删除list.PushBack以及list.Remove操作。也可以模拟栈。
三、AC 代码
数组当栈使用
type CQueue struct {
s1 []int
s2 []int
}
func Constructor() CQueue {
return CQueue{
s1 : []int{},
s2:[]int{},
}
}
//向s1添加内容
func (this *CQueue) AppendTail(value int) {
this.s1 = append(this.s1,value)
}
func (this *CQueue) DeleteHead() int {
if len(this.s2) == 0 {
for len(this.s1) > 0 {
num := this.s1[len(this.s1) -1]
this.s1 = this.s1[:len(this.s1)-1]
this.s2 = append(this.s2,num)
}
}
if len(this.s2) == 0 {
return -1
}
num := this.s2[len(this.s2)-1]
this.s2 = this.s2[:len(this.s2)-1]
return num
}
双向链表当栈使用
type CQueue struct {
s1 *list.List
s2 *list.List
}
func Constructor() CQueue {
return CQueue{
s1 : list.New(),
s2:list.New(),
}
}
//向s1添加内容
func (this *CQueue) AppendTail(value int) {
this.s1.PushBack(value)
}
func (this *CQueue) DeleteHead() int {
if this.s2.Len()== 0 {
for this.s1.Len() != 0 {
e := this.s1.Back()
this.s1.Remove(e)
//类型断言
this.s2.PushBack(e.Value.(int))
}
}
if this.s2.Len() == 0 {
return -1
}
e := this.s2.Back()
this.s2.Remove(e)
return e.Value.(int)
}
/**
* Your CQueue object will be instantiated and called as such:
* obj := Constructor();
* obj.AppendTail(value);
* param_2 := obj.DeleteHead();
*/
四、总结
由于go中没有栈的显式数据结构,我们可以使用数组模拟栈或者是双向链表模拟栈,要注意的是双向链表获取元素时为interface接口类型,通过类型断言可以转换为int,在插入数据的时候即pushback时,也要将interface数据转换为int型插入,类型断言语法为.(int)