该题的解题思路用到了数据结构栈和队列的概念,请查看 栈 和 队列
/**
* @description 两个栈实现一个队列
* @author lsr
*/
export class Queue {
private stack1: number[] = []
private stack2: number[] = []
/**
* 入队
* @param num num
*/
push(num: number) {
this.stack1.push(num)
}
/**
* 出队
* @returns number | null
*/
shift(): number | null {
const stack1 = this.stack1
const stack2 = this.stack2
// 如果 stack2 还有值,直接出队,如果没值复制 stack1,再出队
if (!stack2.length) {
while (stack1.length) {
const n = stack1.pop()
if (n !== undefined) stack2.push(n)
}
}
const res = stack2.pop()
return res || null
}
get length(): number {
return this.stack1.length + this.stack2.length
}
}
// 功能测试
// const q = new Queue()
// q.push(100)
// q.push(200)
// q.push(300)
// q.push(400)
// q.push(500)
// console.log(q.length)
// console.log(q.shift())
// console.log(q.length)
// console.log(q.shift())
// console.log(q.shift())
// console.log(q.shift())
// console.log(q.shift())
// console.log(q.shift())
// q.push(600)
// q.push(700)
// q.push(800)
// console.log(q.length)
// console.log(q.shift())
// console.log(q.shift())
单元测试
/**
* @description 两个栈实现一个队列 test
* @author lsr
*/
import { Queue } from '@/01-algorithm/twoStacks-oneQueue'
describe('两个栈实现一个队列', () => {
it('测试 push 和 length', () => {
const q = new Queue()
q.push(100)
expect(q.length).toBe(1)
q.push(200)
q.push(300)
expect(q.length).toBe(3)
})
it('测试 shift 和 length', () => {
const q = new Queue()
q.push(100)
q.push(200)
q.push(300)
expect(q.length).toBe(3)
const n1 = q.shift()
const n2 = q.shift()
const n3 = q.shift()
expect(n1).toBe(100)
expect(n2).toBe(200)
expect(n3).toBe(300)
expect(q.length).toBe(0)
})
it('测试 shift 最后一个元素后,继续删除', () => {
const q = new Queue()
q.push(100)
q.push(200)
q.push(300)
expect(q.length).toBe(3)
const n1 = q.shift()
const n2 = q.shift()
const n3 = q.shift()
const n4 = q.shift()
expect(n1).toBe(100)
expect(n2).toBe(200)
expect(n3).toBe(300)
expect(q.length).toBe(0)
expect(n4).toBeNull()
expect(q.length).toBe(0)
})
it('测试 shift 最后一个元素后,再push', () => {
const q = new Queue()
q.push(100)
q.push(200)
q.push(300)
expect(q.length).toBe(3)
const n1 = q.shift()
const n2 = q.shift()
const n3 = q.shift()
expect(n1).toBe(100)
expect(n2).toBe(200)
expect(n3).toBe(300)
expect(q.length).toBe(0)
q.push(400)
q.push(500)
expect(q.length).toBe(2)
})
it('测试 shift 最后一个元素后,再 push,再 shift', () => {
const q = new Queue()
q.push(100)
q.push(200)
q.push(300)
expect(q.length).toBe(3)
const n1 = q.shift()
const n2 = q.shift()
const n3 = q.shift()
expect(n1).toBe(100)
expect(n2).toBe(200)
expect(n3).toBe(300)
expect(q.length).toBe(0)
q.push(400)
q.push(500)
expect(q.length).toBe(2)
const n4 = q.shift()
expect(n4).toBe(400)
expect(q.length).toBe(1)
})
})
复杂度分析
- 时间复杂度:push O(1)、shift O(n)
- 空间复杂度:O(n)
划重点
- 队列
- 逻辑结构 vs 物理结构
- 将思路在纸上画出来