代码随想录算法训练营Day10

101 阅读3分钟

代码随想录算法训练营Day10

232.用栈实现队列

思路

首先需要清楚栈具有**后进先出(LIFO)的特性,如果想模拟队列先进先出(FIFO)**的行为,应该至少需要两个栈来实现。

根据题目要求,使用两个栈实现队列的思路如下:

  1. 两个栈的使用:使用两个栈,一个作为输入栈(用于入队操作),另一个作为输出栈(用于出队操作)。
  2. 入队操作:当有新元素需要入队时,直接将元素压入输入栈。
  3. 出队操作
    • 如果输出栈为空,将输入栈的所有元素依次弹出并压入输出栈。
    • 然后从输出栈弹出栈顶元素,即为队列的队首元素。
    • 如果队列为空,返回-1。
    • peek操作:取出兑操作返回值val。
    • 如果val为-1,说明队空,则本函数也返回-1。
    • 如果val不为-1,记录val值,并将val重新放人输出栈,恢复原样
  4. 判定队空:在执行出队操作之前,需检查输出栈是否为空。如果两个栈都为空,则表示队列为空。

代码实现

type MyQueue struct {
	stackIn  []int //输入栈
	stackOut []int //输出栈
}

func Constructor() MyQueue {
	return MyQueue{
		stackIn:  make([]int, 0),
		stackOut: make([]int, 0),
	}
}

func (this *MyQueue) Push(x int) {
	//push操作需要往
	this.stackIn = append(this.stackIn, x)
}

func (this *MyQueue) Pop() int {
	inLen, outLen := len(this.stackIn), len(this.stackOut)
	if outLen == 0 {
		//如果输出栈为空,则尝试从输入栈弹出数据
		if inLen == 0 {
			//如果输入栈还是为空,则弹出-1
			return -1
		}
		//如果输入栈不为空,则将输入栈所有元素依次弹出并压入输出栈
		for i := inLen - 1; i >= 0; i-- {
			this.stackOut = append(this.stackOut, this.stackIn[i])
		}
		this.stackIn = []int{}      //导出后清空
		outLen = len(this.stackOut) //更新长度值
	}
	//输出栈栈顶作为pop对象
	out := this.stackOut[outLen-1]
	//收缩输出栈
	this.stackOut = this.stackOut[:outLen-1]
	return out
}

func (this *MyQueue) Peek() int {
	peek := this.Pop()
	if peek == -1 {
		// 如果pop失败,则返回-1
		return -1
	}
	//pop之后,需要把peek添加回去
	this.stackOut = append(this.stackOut, peek)
	return peek
}

func (this *MyQueue) Empty() bool {
	if len(this.stackIn) == 0 && len(this.stackOut) == 0 {
		//两个栈都是空,则队空
		return true
	}
	return false
}

image-20240114015927373

225.用队列实现栈

思路

只使用一个队列,通过改变队列中元素的顺序来模拟栈的操作,使得最后入队的元素始终位于队列的前端,从而实现栈的特性:

  1. 入栈操作:将新元素加入队列的末尾。然后,将队列中原有的所有元素依次出队并再次入队(加入到队列末尾),使得新加入的元素移到队列的前端。
  2. 出栈操作:由于最后入栈的元素位于队列的前端,直接出队即可,这模拟了栈的后进先出特性。
  3. 取栈顶操作:由于栈顶元素位于队列的前端,直接访问队列的前端元素即可得到栈顶元素。
  4. 栈判空操作:检查队列是否为空。

代码实现

type MyStack struct {
    queue []int
}

func Constructor() MyStack {
    return MyStack{queue: []int{}}
}

func (this *MyStack) Push(x int) {
    n := len(this.queue)
    this.queue = append(this.queue, x)
    for i := 0; i < n; i++ {
        // 将队列前端的元素移动到队列末尾
        this.queue = append(this.queue, this.queue[0])
        this.queue = this.queue[1:]
    }
}

func (this *MyStack) Pop() int {
    if len(this.queue) == 0 {
        return -1 // 或者其他错误处理
    }
    x := this.queue[0]
    this.queue = this.queue[1:]
    return x
}

func (this *MyStack) Top() int {
    if len(this.queue) == 0 {
        return -1 // 或者其他错误处理
    }
    return this.queue[0]
}

func (this *MyStack) Empty() bool {
    return len(this.queue) == 0
}

image-20240114022318671