算法:两个栈实现一个队列

38 阅读1分钟
  • 请用两个栈,实现一个队列
  • 功能 add delete length

队列

  • 先进先出
  • API: add delete length

image.png

数组模拟队列

存在shift性能问题

const queue:number[] = []

queue.push(100)
queue.push(200)
queue.push(300)
const n = queue.shift()

逻辑结构vs物理结构

  • 队列是逻辑结构,抽象模型
  • 简单的,可以用数组、链表实现
  • 复杂的队列服务,需要单独设计

画图分析:

image.png

class MyQueue {
  private stack1: number[] = []
  private stack2: number[] = []
  add(n: number) {
    // 入队
    this.stack1.push(n)
  }
  delete(): number | null {
    let res
    const stack1 = this.stack1
    const stack2 = this.stack2
    // 将stack1 所有元素移动到stack2中
    while (stack1.length) {
      let n = stack1.pop()
      if (n != null) {
        stack2.push(n)
      }
    }

    res = stack2.pop()
    // 将stack2 所有元素还给stack1
    while (stack2.length) {
      let n = stack2.pop()
      if (n != null) {
        stack1.push(n)
      }
    }

    return res || null
  } // 出队

  get length(): number {
    return this.stack1.length
  }
}

// 功能测试

const q = new MyQueue()
q.add(10)
q.add(20)
q.add(30)
console.log(q.length);
console.log(q.delete());
console.log(q.length)

jest单元测试

import { MyQueue } from './两个栈实现一个队列'

describe('两个栈,一个队列', () => {
  it('add and length', () => {
    const q = new MyQueue()
    expect(q.length).toBe(0)
    q.add(100)
    q.add(200)
    q.add(300)
    expect(q.length).toBe(3)
  })
  it('delete', () => {
    const q = new MyQueue()
    expect(q.delete).toBe(null)
    q.add(100)
    q.add(200)
    q.add(300)
    expect(q.delete()).toBe(100)
    expect(q.length).toBe(2)
    expect(q.delete()).toBe(200)
    expect(q.length).toBe(1)
  })
})

性能分析

  • 时间复杂度: add O(1) delete O(n)
  • 空间复杂度,整体是O(n)