如何獲取棧的最小值
阿新 • • 發佈:2018-11-01
1、基本方法:增加輔助棧,輔助棧裡面儲存每次存放的最小值。如圖所示原理,
程式碼實現:
public class MinStack1 { private List<Integer> data = new ArrayList<Integer>(); private List<Integer> mins = new ArrayList<Integer>(); public void push(int num) { data.add(num); if (mins.size() == 0) { // 初始化mins mins.add(num); } else { // 輔助棧mins每次push當時最小值 int min = getMin(); if (num >= min) { mins.add(min); } else { mins.add(num); } } } public int pop() { // 棧空,異常,返回-1 if (data.size() == 0) { return -1; } // pop時兩棧同步pop mins.remove(mins.size() - 1); return data.remove(data.size() - 1); } public int getMin() { // 棧空,異常,返回-1 if (mins.size() == 0) { return -1; } // 返回mins棧頂元素 return mins.get(mins.size() - 1); } }
存在問題:
1.異常處理存在問題:這裡定的是-1的異常返回值,但是當棧內為空的時候,返回的是-1,如果使用者push過-1,那麼返回的-1到底是使用者push進來的值,還是棧為空,這個是個矛盾點。
2.輔助棧資料冗餘的問題:
2、正確的解鎖姿勢(最優):用輔助棧記錄儲存資料最小值的下標。
mins 棧中改存最小值在 data 陣列中的索引。這樣一來,當 push 了與最小值相同元素的時候,就不需要動 mins 棧了。
而 pop 的時候,pop 出的元素的索引如果不是 mins 棧頂元素,mins 也不出棧。
同時,獲取最小值的時候,需要拿到 mins 棧頂元素作為索引,再去 data 陣列中找到相應的數作為最小值。
程式碼實現:
public class MinStack2 { private List<Integer> data = new ArrayList<Integer>(); private List<Integer> mins = new ArrayList<Integer>(); public void push(int num) throws Exception { data.add(num); if (mins.size() == 0) { // 初始化mins mins.add(0); } else { // 輔助棧mins push最小值的索引 int min = getMin(); if (num < min) { mins.add(data.size() - 1); } } } public int pop() throws Exception { // 棧空,丟擲異常 if (data.size() == 0) { throw new Exception("棧為空"); } // pop時先獲取索引 int popIndex = data.size() - 1; // 獲取mins棧頂元素,它是最小值索引 int minIndex = mins.get(mins.size() - 1); // 如果pop出去的索引就是最小值索引,mins才出棧 if (popIndex == minIndex) { mins.remove(mins.size() - 1); } return data.remove(data.size() - 1); } public int getMin() throws Exception { // 棧空,丟擲異常 if (data.size() == 0) { throw new Exception("棧為空"); } // 獲取mins棧頂元素,它是最小值索引 int minIndex = mins.get(mins.size() - 1); return data.get(minIndex); } }
參考資料:公眾號網際網路偵察