设计一个有GetMin功能的栈

实现一个特殊栈,并能返回栈中最小元素

两种数据压入规则,也就是两种实现的方法,利用两个栈,一个stackData栈用来压入所有的数据,所有数据都会压入此栈,一个satckMin用来压入最小元素(对应的就是stackData中的最小元素)。

第一种方法:

(压栈规则):

(1)当将数据压入栈stackData时,判断stackMin栈是否为空,为空则将此数据也压入stackMin栈。

(2)若stackMin栈不为空,则将这个要压入satckData的数据,与stackMin的栈顶元素比较(也就是原来stackMin栈中的最小元素),如果此数据比stackMin的栈顶元素更小或者相等,则将此数据同步压入stackMin栈,成为新的最小元素。反之则不压入。

(出栈规则):

(1)当stackData栈弹出数据时,设此元素为value。然后比较此数据与stackMin的栈顶元素。若相等,则双栈同步弹出元素,若大于,则satckMin栈不弹出栈顶元素。此出栈规则其实与压栈规则是相对应的。同时我们也知道,因为stackMin中栈顶元素只可能是双栈的最小元素,所以不存在在出栈时stackData中数据大于stackMin中的元素的情况。否则说明我们的压栈规则是不合理的,功能并没有实现。

具体实现如下:

第一种方法:

public class GetMinStack {
	private Stack<Integer> stackData;//栈数据
	private Stack<Integer> stackMin;//放置最小元素的栈
	public GetMinStack() {
		this.stackData = new Stack<Integer>();
		this.stackMin = new Stack<Integer>();
		
	}
	public void push(int newNum) {//压栈
		if(this.stackMin.isEmpty()) {
			this.stackMin.push(newNum);
		}else if(newNum <= this.getMin()) {
			this.stackMin.push(newNum);
		}
		this.stackData.push(newNum);
	}
	public int pop() {//出栈
		if(this.stackData.isEmpty()) {
			throw new RuntimeException("your stack is empty");
		}
		 int value  = this.stackData.pop();
         if(value == this.getMin()){
             this.stackMin.pop();
         }
         return value;
        //this.stackMin.pop();
		//return this.stackData.pop();
	}
private int getMin() {
		// TODO Auto-generated method stub
		if(this.stackMin.isEmpty()) {
			System.out.println("your stack is empty");
		}
		return this.stackMin.peek();
		
	}
}

第二种方法:

压栈规则与第一种类似:

(1)第一步与上面的第一步相同。

(2)当stackData压入的数据小于或等于stackMin的栈顶元素时,则将此数据也同步压入stackMin。反之则将stackMin中的栈顶元素再重复压入一次stackMin栈。

出栈规则:

(1)与压栈规则相对应,每次都是双栈一起出栈,而不存在比较后stackMin不出栈的情况,因为此种规则下,双栈元素数量相同,同位置的stackMin中的栈顶元素总是双栈中的最小元素。

第二种方法:

public static class Mystack2{
		
		private Stack<Integer> stackData;//栈数据
		private Stack<Integer> stackMin;//最小
		public Mystack2() {
			this.stackData = new Stack<Integer>();
			this.stackMin = new Stack<Integer>();
			
		}
		public void push(int newNum) {
			if(this.stackMin.isEmpty()) {
				this.stackMin.push(newNum);
			}else if(newNum<this.getMin()) {
				this.stackMin.push(newNum);
			}
			else {
				int newMin = this.stackMin.peek();
				this.stackMin.push(newMin);
			}
			this.stackData.push(newNum);
		}
	    public int pop() {
				if (this.stackData.isEmpty()) {
					throw new RuntimeException("Your stack is empty.");
				}
				this.stackMin.pop();
				return this.stackData.pop();
		}

		public int getMin() {
			if (this.stackMin.isEmpty()) {
				throw new RuntimeException("Your stack is empty.");
			}
			return this.stackMin.peek();
		}
		
	}

测试代码:

public static void main(String[] args) {
		GetMinStack stack1 = new GetMinStack();
		stack1.push(3);
		System.out.println(stack1.getMin());
		stack1.push(4);
		System.out.println(stack1.getMin());
		stack1.push(2);
		System.out.println(stack1.getMin());
		stack1.push(5);
		System.out.println(stack1.pop());
		System.out.println(stack1.getMin());
		stack1.push(2);
		System.out.println(stack1.getMin());
		System.out.println(stack1.pop());
		System.out.println(stack1.getMin());
		//System.exit(0);
		
		

		System.out.println("=============");

		Mystack2 stack2 = new Mystack2();
		stack2.push(3);
		System.out.println(stack2.getMin());
		stack2.push(4);
		System.out.println(stack2.getMin());
		stack2.push(1);
		System.out.println(stack2.getMin());
		System.out.println(stack2.pop());
		System.out.println(stack2.getMin());
	}

此算法参考了《程序员代码面试指南一书》,说一个小问题,因为第一个方法出栈规则时经过比较后才决定stackMin栈顶元素是否出栈,所以出栈代码与第二种是不同的,参考的代码中,两种出栈代码相同,也就是第一种中出栈方法中注释掉的那段代码是错误的。希望能引起注意。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值