1. 程式人生 > >如何獲取棧的最小值

如何獲取棧的最小值

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);
	}
}

 

 

參考資料:公眾號網際網路偵察

 

每天努力一點,每天都在進步。