diff --git a/.vscode/settings.json b/.vscode/settings.json
index 8f2ef8c..54c94bd 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -19,6 +19,7 @@
"lcov",
"leetcode",
"leetcodeisgreat",
+ "liang",
"lrloseumgh",
"mincost",
"nums",
@@ -32,6 +33,7 @@
"subarrays",
"umghlrlose",
"xuan",
+ "zhan",
"zhong",
"zhuan"
]
diff --git a/README.md b/README.md
index c0849c3..f2f703d 100644
--- a/README.md
+++ b/README.md
@@ -365,6 +365,10 @@ LeetCode 与 LintCode 解题记录。此为个人练习仓库,代码中对重
- LeetCode 155. 最小栈
- LintCode 12. 带最小值操作的栈
+- [用两个栈实现队列](src/stack/yong-liang-ge-zhan-shi-xian-dui-lie-lcof.js)
+
+ - LeetCode 剑指 Offer 09. 用两个栈实现队列
+
## 数学
- [阶乘后的零](src/math/factorial-trailing-zeroes.js)
diff --git a/src/stack/yong-liang-ge-zhan-shi-xian-dui-lie-lcof.js b/src/stack/yong-liang-ge-zhan-shi-xian-dui-lie-lcof.js
new file mode 100644
index 0000000..ea924b8
--- /dev/null
+++ b/src/stack/yong-liang-ge-zhan-shi-xian-dui-lie-lcof.js
@@ -0,0 +1,37 @@
+export var CQueue = function () {
+ this.stackA = []
+ this.stackB = []
+}
+
+/**
+ * @param {number} value
+ * @return {void}
+ */
+CQueue.prototype.appendTail = function (value) {
+ this.stackA.push(value)
+}
+
+/**
+ * @return {number}
+ */
+CQueue.prototype.deleteHead = function () {
+ const stackBNum = this.stackB.length
+
+ while (this.stackA.length) {
+ this.stackB.push(this.stackA.pop())
+ }
+
+ if (stackBNum !== 0) {
+ this.stackB.push(...this.stackB.splice(0, stackBNum))
+ }
+
+ const tmp = this.stackB.pop()
+ return tmp === undefined ? -1 : tmp
+}
+
+/**
+ * Your CQueue object will be instantiated and called as such:
+ * var obj = new CQueue()
+ * obj.appendTail(value)
+ * var param_2 = obj.deleteHead()
+ */
diff --git a/test/stack/yong-liang-ge-zhan-shi-xian-dui-lie-lcof.test.js b/test/stack/yong-liang-ge-zhan-shi-xian-dui-lie-lcof.test.js
new file mode 100644
index 0000000..c73465a
--- /dev/null
+++ b/test/stack/yong-liang-ge-zhan-shi-xian-dui-lie-lcof.test.js
@@ -0,0 +1,67 @@
+import { CQueue } from '../../src/stack/yong-liang-ge-zhan-shi-xian-dui-lie-lcof.js'
+
+test('用两个栈实现队列 - 1', () => {
+ let obj = null
+ const action = ['CQueue', 'appendTail', 'deleteHead', 'deleteHead']
+ const queue = [[], [3], [], []]
+ const res = []
+ while (queue.length) {
+ const tmp = action.shift()
+ const val = queue.shift()
+ if (tmp === 'CQueue') {
+ obj = new CQueue()
+ res.push(null)
+ } else if (tmp === 'appendTail') {
+ obj.appendTail(val[0])
+ res.push(null)
+ } else if (tmp === 'deleteHead') {
+ res.push(obj.deleteHead())
+ }
+ }
+
+ expect(res).toEqual([null, null, 3, -1])
+})
+
+test('用两个栈实现队列 - 2', () => {
+ let obj = null
+ const action = ['CQueue', 'deleteHead', 'appendTail', 'appendTail', 'deleteHead', 'deleteHead']
+ const queue = [[], [], [5], [2], [], []]
+ const res = []
+ while (queue.length) {
+ const tmp = action.shift()
+ const val = queue.shift()
+ if (tmp === 'CQueue') {
+ obj = new CQueue()
+ res.push(null)
+ } else if (tmp === 'appendTail') {
+ obj.appendTail(val[0])
+ res.push(null)
+ } else if (tmp === 'deleteHead') {
+ res.push(obj.deleteHead())
+ }
+ }
+
+ expect(res).toEqual([null, -1, null, null, 5, 2])
+})
+
+test('用两个栈实现队列 - 3', () => {
+ let obj = null
+ const action = ['CQueue', 'deleteHead', 'appendTail', 'deleteHead', 'deleteHead', 'deleteHead', 'deleteHead', 'appendTail', 'deleteHead', 'appendTail', 'appendTail', 'deleteHead', 'deleteHead', 'deleteHead', 'appendTail', 'deleteHead', 'deleteHead', 'deleteHead', 'deleteHead', 'appendTail', 'appendTail', 'appendTail', 'appendTail', 'deleteHead', 'deleteHead', 'appendTail', 'appendTail', 'deleteHead', 'deleteHead', 'deleteHead', 'appendTail', 'appendTail', 'deleteHead', 'appendTail', 'deleteHead', 'appendTail', 'appendTail', 'appendTail', 'deleteHead', 'deleteHead', 'appendTail', 'appendTail', 'deleteHead', 'deleteHead', 'deleteHead', 'deleteHead', 'appendTail', 'appendTail', 'deleteHead', 'deleteHead', 'appendTail', 'deleteHead', 'appendTail', 'appendTail', 'appendTail', 'appendTail', 'deleteHead', 'appendTail', 'deleteHead', 'deleteHead', 'appendTail', 'appendTail', 'appendTail', 'deleteHead', 'deleteHead', 'appendTail', 'appendTail', 'appendTail', 'deleteHead', 'deleteHead', 'deleteHead', 'deleteHead', 'appendTail', 'appendTail', 'deleteHead', 'deleteHead', 'appendTail', 'deleteHead', 'appendTail', 'appendTail', 'deleteHead', 'deleteHead', 'appendTail', 'deleteHead', 'appendTail', 'appendTail', 'appendTail', 'deleteHead', 'appendTail', 'appendTail', 'appendTail', 'appendTail', 'deleteHead', 'deleteHead', 'deleteHead', 'appendTail', 'deleteHead', 'appendTail', 'deleteHead', 'appendTail', 'appendTail']
+ const queue = [[], [], [97], [], [], [], [], [15], [], [1], [43], [], [], [], [18], [], [], [], [], [36], [69], [21], [91], [], [], [22], [40], [], [], [], [81], [65], [], [77], [], [63], [96], [5], [], [], [35], [90], [], [], [], [], [77], [83], [], [], [52], [], [2], [66], [87], [90], [], [2], [], [], [33], [16], [72], [], [], [14], [78], [8], [], [], [], [], [3], [83], [], [], [13], [], [79], [44], [], [], [33], [], [55], [76], [12], [], [91], [24], [49], [47], [], [], [], [85], [], [69], [], [94], [52]]
+ const res = []
+ while (queue.length) {
+ const tmp = action.shift()
+ const val = queue.shift()
+ if (tmp === 'CQueue') {
+ obj = new CQueue()
+ res.push(null)
+ } else if (tmp === 'appendTail') {
+ obj.appendTail(val[0])
+ res.push(null)
+ } else if (tmp === 'deleteHead') {
+ res.push(obj.deleteHead())
+ }
+ }
+
+ expect(res).toEqual([null, -1, null, 97, -1, -1, -1, null, 15, null, null, 1, 43, -1, null, 18, -1, -1, -1, null, null, null, null, 36, 69, null, null, 21, 91, 22, null, null, 40, null, 81, null, null, null, 65, 77, null, null, 63, 96, 5, 35, null, null, 90, 77, null, 83, null, null, null, null, 52, null, 2, 66, null, null, null, 87, 90, null, null, null, 2, 33, 16, 72, null, null, 14, 78, null, 8, null, null, 3, 83, null, 13, null, null, null, 79, null, null, null, null, 44, 33, 55, null, 76, null, 12, null, null])
+})