剑指offer 09用两个栈实现队列 Kotlin

题目描述

用两个栈来实现一个队列,使用n个元素来完成 n 次在队列尾部插入整数(push)和n次在队列头部删除整数(pop)的功能。 队列中的元素为int类型。保证操作合法,即保证pop操作时队列内已有元素。

数据范围: n≤1000n≤1000

要求:存储n个元素的空间复杂度为 O(n)O(n) ,插入与删除的时间复杂度都是 O(1)O(1)

题目分析

首先,题目明确指出我们只能使用两个栈作为数据结构,并且队列中的元素必须是整数类型。这意味着我们不能依赖队列或其他数据结构的特性,而必须完全依靠栈的操作来实现队列的功能。

接下来,题目要求我们支持 n 次的 push 操作和 n 次的 pop 操作。push 操作需要在队列尾部插入元素,而 pop 操作需要从队列头部移除元素。重要的是,pop 操作必须在队列非空的情况下执行,以避免非法操作。

此外,题目对性能有严格的要求。存储 n 个元素的空间复杂度必须是 O(n),而 pushpop 操作的时间复杂度都必须是 O(1)。这要求我们的实现必须高效,以保证操作的快速性。

解题思路

首先,我们得明白栈和队列的区别。栈是后进先出,队列是先进先出。我们要用两个栈来模拟队列的行为。

  1. 入队操作:将元素推入 stackIn,这是一个直接的栈操作,模拟队列的入队行为。

  2. 出队操作:这是实现中的关键部分。如果 stackOut 不为空,我们直接从 stackOut 弹出元素,这模拟了队列的出队行为。如果 stackOut 为空,我们需要将 stackIn 中的所有元素转移到 stackOut,这一步骤虽然时间复杂度为 O(n),但由于其在整个操作序列中只发生一次,因此不会影响 pop 操作的整体平均时间复杂度。

  3. 性能保证:通过上述策略,我们可以确保 push 操作的时间复杂度为 O(1),而 pop 操作在大多数情况下也是 O(1),只有在 stackOut 为空时需要进行一次额外的元素转移。

  4. 单例对象的使用:我们将实现封装在一个单例对象 Solution 中,这样可以确保全局只有一个队列实例,并且可以通过这个单例对象来执行所有队列操作。

具体实现

object Solution {
    private val stackIn = mutableListOf<Int>() // 用于入队的栈
    private val stackOut = mutableListOf<Int>() // 用于出队的栈

    /**
     * 入队操作
     * @param node int整型 入队的元素
     * @return 无
     */
    fun push(node: Int) {
        stackIn.add(node)
    }

    /**
     * 出队操作
     * @param 无
     * @return int整型 队列头部的元素
     */
    fun pop(): Int {
        if (stackOut.isEmpty()) {
            // 当stackOut为空时,将stackIn中的元素依次压入stackOut,实现反转
            while (stackIn.isNotEmpty()) {
                stackOut.add(0, stackIn.removeAt(stackIn.lastIndex))
            }
        }
        // 弹出并返回stackOut的第一个元素,即队列的队首元素
        return stackOut.removeAt(0)
    }
}

fun main() {
    // 执行入队操作
    repeat(5) {
        Solution.push(it + 1)
    }

    // 执行出队操作,并打印结果
    repeat(5) {
        println("Popped item: ${Solution.pop()}")
    }
}

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值