Cracking the coding interview--Q3.2

题目

原文:

How would you design a stack which, in addition to push and pop, also has a function min which returns the minimum element? Push, pop and min should all operate in O(1) time.

译文:

设计一个栈,除了push和pop方法外,还有一个min的函数能够返回最小的元素,并且push,pop,min的时间复杂度都为O(1)

解答

首先想到找出栈中最小元素,可以通过每push一个值就作比较,从而得出最小元素,但一旦最小元素在栈顶,执行了pop方法,最小元素出栈,那么就无法在O(1)的时间内找到最小值了,显然这种方法是不可行的。所以,可以考虑每一个元素维护一个指向从当前元素到栈底元素的最小值的指针,如下面例子:

Cracking the coding interview--Q3.2_第1张图片


不过可以发现这样存储,浪费很多空间,因此,可以引入另外一个栈S,当每次入栈或者出栈的时候,都通这个额外栈的栈顶元素比较一下。入栈的时候,如果入栈元素大于S栈顶元素,S栈顶元素不变。否则,将入栈元素也压入到栈S中,使栈S保持一个局部的最小值;出栈的时候,如果出栈元素大于S栈顶元素,S栈顶元素不变。否则,将S栈的栈顶元素也一同出栈。

以下是利用LinkedList的栈结构来实现具有min()的栈的:

import java.util.*;

class Q3_2{
	public static void main(String[] args) {
		StackWithMin1 s1 = new StackWithMin1();
		StackWithMin2 s2 = new StackWithMin2();
		int[] arr = new int[]{6,3,4,6,9,1};
		for(int i=0;i<arr.length;i++){
			s1.push(arr[i]);
			s2.push(arr[i]);
		}
		System.out.println(s1.min());
		System.out.println(s2.min());
		s1.pop();
		s2.pop();
		System.out.println(s1.min());
		System.out.println(s2.min());
	}
}

class StackWithMin1{
	LinkedList<Integer[]> values ;
	public StackWithMin1(){
		values = new LinkedList<Integer[]>();
	}
	
	public int  pop(){
		return values.pop()[0];
	}
	public void push(int val){
		//第一个元素入栈设置初始最小值
		if(values.peek()==null){
			values.push(new Integer[]{val,val});
		}
		int min = values.peek()[1];
		if(min<val){
			values.push(new Integer[]{val,min});
		}else{
			values.push(new Integer[]{val,val});
		}
	}
	public int min(){
		int min = values.pop()[1];
		return min;
	}
	
}
class StackWithMin2{
	LinkedList<Integer> values;
	LinkedList<Integer> S;//额外栈
	public StackWithMin2(){
		values = new LinkedList<Integer>();
		S = new LinkedList<Integer>();
	}
	public void push(int val ){
		Integer sPeek = S.peek();
		values.push(val);
		if(sPeek==null||val<=sPeek){
			S.push(val);
		}
	}
	public int pop(){
		Integer t = values.pop();
		if(t<=S.peek()){
			S.pop();
		}
		return t;
	}
	public int min(){
		return S.peek();
	}
}

如有更好的方法,还望交流!

---EOF---

你可能感兴趣的:(Cracking the coding interview--Q3.2)