一、題目:包含Min函數的棧
題目:定義棧的數據結構,請在該類型中實現一個能夠得到棧的最小元素的min函數。在該棧中,調用min、push及pop的時間復雜度都是O(1)。
這里我們要實現的就是min、push以及pop三個方法:
public class MinInStack<T> where T : struct { private Stack<T> dataStack; private Stack<T> minStack; public MinInStack() { this.dataStack = new Stack<T>(); this.minStack = new Stack<T>(); } public bool IsEmpty() { return this.dataStack.Count == 0; } public T Top() { return this.dataStack.Peek(); } public void Push(T item) { } public T Pop() { } public T Min() { } }
二、解題思路
2.1 核心步驟
把每次的最小元素(之前的最小元素和新壓入棧的元素兩者的較小值)都保存起來放到另外一個輔助棧里。下圖展示了棧內壓入3、4、2、1之后接連兩次彈出棧頂數字再壓入0時,數據棧、輔助棧和最小值的狀態。

從表中我們可以看出,如果每次都把最小元素壓入輔助棧,那么就能保證輔助棧的棧頂一直都是最小元素。
2.2 代碼實現
(1)Push方法
public void Push(T item) { // 把新元素添加到數據棧 dataStack.Push(item); // 當新元素比之前的最小元素小時,把新元素插入輔助棧里; // 否則把之前的最小元素重復插入輔助棧里 if (minStack.Count == 0 || item.CompareTo(minStack.Peek()) < 0) { minStack.Push(item); } else { minStack.Push(minStack.Peek()); } }
(2)Pop方法
public T Pop() { T item = dataStack.Pop(); if(minStack.Count > 0) { minStack.Pop(); } return item; }
(3)Min方法
public T Min() { return minStack.Peek(); }
三、單元測試
3.1 測試用例
[TestMethod] public void MinTest1() { MinInStack<int> stack = new MinInStack<int>(); stack.Push(3); Assert.AreEqual(stack.Min(),3); } [TestMethod] public void MinTest2() { MinInStack<int> stack = new MinInStack<int>(); stack.Push(3); stack.Push(4); Assert.AreEqual(stack.Min(), 3); } [TestMethod] public void MinTest3() { MinInStack<int> stack = new MinInStack<int>(); stack.Push(3); stack.Push(4); stack.Push(2); Assert.AreEqual(stack.Min(), 2); } [TestMethod] public void MinTest4() { MinInStack<int> stack = new MinInStack<int>(); stack.Push(3); stack.Push(4); stack.Push(2); stack.Push(3); Assert.AreEqual(stack.Min(), 2); } [TestMethod] public void MinTest5() { MinInStack<int> stack = new MinInStack<int>(); stack.Push(3); stack.Push(4); stack.Push(2); stack.Push(3); stack.Pop(); Assert.AreEqual(stack.Min(), 2); } [TestMethod] public void MinTest6() { MinInStack<int> stack = new MinInStack<int>(); stack.Push(3); stack.Push(4); stack.Push(2); stack.Push(3); stack.Pop(); stack.Pop(); Assert.AreEqual(stack.Min(), 3); } [TestMethod] public void MinTest7() { MinInStack<int> stack = new MinInStack<int>(); stack.Push(3); stack.Push(4); stack.Push(2); stack.Push(3); stack.Pop(); stack.Pop(); stack.Pop(); Assert.AreEqual(stack.Min(), 3); } [TestMethod] public void MinTest8() { MinInStack<int> stack = new MinInStack<int>(); stack.Push(3); stack.Push(4); stack.Push(2); stack.Push(3); stack.Pop(); stack.Pop(); stack.Pop(); stack.Push(0); Assert.AreEqual(stack.Min(), 0); }
3.2 測試結果
(1)測試通過情況

(2)代碼覆蓋率

