首页 > 其他 > 详细

《微软面试100题 In Java》02.Stack and minimum element in O(1)

时间:2014-03-08 09:51:09      阅读:493      评论:0      收藏:0      [点我收藏+]

题目: 定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素。要求函数min、push以及pop的时间复杂度都是O(1)。

分析:首先栈的push和pop时间复杂度都是O(1)的,但是对于min函数在没有排序的队列里一般时间复杂度是O(n).首先我想的是当我们push元素时我们定于一个临时的参数x,表示当前最小数,每次push元素时都进行比较更新,这样好像也能成功,但是当我们记录的元素被pop掉了呢,我们无从知道第二小的元素了,所以此时我们需要借助一个栈来记录下曾经保存下来的最小数。于是就有的第一种解法:

Solution 1: With Auxiliary Stack

Step
Operation
Data Stack
Auxiliary Stack
Minimum
1
Push 3
3
3
3
2
Push 4
3, 4
3, 3
3
3
Push 2
3, 4, 2
3, 3, 2
2
4
Push 1
3, 4, 2, 1
3, 3, 2, 1
1
5
Pop
3, 4, 2
3, 3, 2
2
6
Pop
3, 4
3, 3
3
7
Push 0
3, 4, 0
3, 3, 0
0
如图中我们了解到,辅助栈中每次都存储当前最小数。原栈pop的时候辅助栈也pop。

class Node{
		public int item ;
		public Node next ;
		
		public int getValue(){ return item ;}
}
class MyStack{
	int N ; //size of myStack
	Node first ; // the top of stack
	
	
	//size of mystack
	public int size(){ return N ;}
	
	//empty or not
	public boolean isEmpty(){ return N==0 ;}
	
	
}
class MyStackMin{
	private MyStack stackData = new MyStack() ; //原stack
	private MyStack stackMin = new MyStack() ;	//辅助stack
	private int minNum ; //
	
	//push element to stack
	public void push(int newItem){
		//给新节点赋值
		Node newNode = new Node() ;
		newNode.item = newItem ;
		
		if(stackData.isEmpty()){
			stackData.first = newNode ;
			
			minNum = newItem ;     //the minNum
			Node minNode = new Node() ;
			minNode.item = minNum ;
			stackMin.first = minNode ;
			stackData.N++ ;
		}else{
			//给辅助stack push
			if(stackData.first.item>newItem){ minNum = newItem ;} //compare the push numble to the first
			Node minNode = new Node() ;
			minNode.item = minNum ;
			minNode.next = stackMin.first ;
			stackMin.first = minNode ;
			
			//push数据到原stack
			newNode.next = stackData.first ;
			stackData.first = newNode ;
			stackData.N++ ;
		}
	}
	
	//pop element from stack
	public void pop(){
		if(stackData.isEmpty()){
			System.out.println("error") ;
		}else{
			stackData.first = stackData.first.next ;
			
			stackMin.first = stackMin.first.next ;
		}
	}
	//search the min numble
	public int min(){
		return stackMin.first.getValue() ;
	}
}
public class StackMin{
	public static void main(String args[]){
		MyStackMin stack = new MyStackMin() ;
		stack.push(3) ;
		System.out.println(stack.min()) ;
		stack.push(4) ;
		System.out.println(stack.min()) ;
		stack.push(2) ;
		System.out.println(stack.min()) ;
		stack.push(1) ;
		System.out.println(stack.min()) ;
		stack.pop() ;
		System.out.println(stack.min()) ;
		stack.pop() ;
		System.out.println(stack.min()) ;
		stack.push(0) ;
		System.out.println(stack.min()) ;
	}
}

总结:1.链表实现栈 2.栈的pop和push 3.双栈实现


Solution 2: Without Auxiliary Stack


方案一我们是利用一个辅助stack来解决了当最小数被pop后无法寻找到第二小的数。那么不用辅助stack可以么,毕竟利用一个辅助浪费了空间和时间,当然可以,我们可以利用小小的改变来实现。就是存入栈中的数据时经过处理的。

Supposing that we are going to push a number value into a stack with minimum number min. Ifvalue is greater than or equal to the min, it is pushed directly into data stack. If it is less than min, we push 2*value -min, and update min as value since a new minimum number is pushed. How about to pop? We pop it directly if the top of data stack (it is denoted as top) is greater than or equal to min. Otherwise the number top is not the real pushed number. The real pushed number is stored is min. After the current minimum number is popped, we need to restore the previous minimum number, which is 2*min-top.

class MyStack{
	private int N ;
	private Node first ;
	private int minNum ;
	
	private class Node{
		private int item ;
		private Node next ;
		
		public int getItem(){ return item ;}
	}
	
	public boolean isEmpty(){ return N==0 ;}
	
	public void push(int newItem){
		Node newNode = new Node() ;
		
		if(isEmpty()){
			newNode.item = newItem ;
			minNum = newItem ;
			
			this.first = newNode ;
			N++ ;
		}else{
			if(newItem<minNum){
				newNode.item = 2*newItem -minNum ; //所经过的处理
				newNode.next = this.first ;
				this.first = newNode ;
				minNum = newItem ;
				N++ ;
			}else{
				newNode.item = newItem ;
				newNode.next = this.first ;
				this.first = newNode ;
				N++ ;
			}
		}
	}
	public void pop(){
		if(isEmpty()){
			System.out.println("error") ;
		}else{
			if(this.first.getItem()<minNum){
				minNum = 2*minNum-this.first.getItem() ;
			}
			this.first = this.first.next ;
		}
	}
	public int min(){
		return minNum ;
	}
}

public class StackMin2{
	public static void main(String args[]){
		MyStack stack = new MyStack() ;
		stack.push(3) ;
		System.out.println(stack.min()) ;
		stack.push(4) ;
		System.out.println(stack.min()) ;
		stack.push(2) ;
		System.out.println(stack.min()) ;
		stack.push(1) ;
		System.out.println(stack.min()) ;
		stack.pop() ;
		System.out.println(stack.min()) ;
		stack.pop() ;
		System.out.println(stack.min()) ;
		stack.push(0) ;
		System.out.println(stack.min()) ;
	}
}

总结:跟上个方案的差别只是没有利用到辅助栈,只是利用的一个算式将第二小的数存储于最小数和存在栈中最小数的值(经过处理的2*最小数-第二小的数)之中。然后还原第二小数的算式为 2*最小数-(2*最小数-第二小的数)


Reference:

http://codercareer.blogspot.com/2011/09/no-02-stack-with-function-min.html

http://mydevelopedworld.wordpress.com/2012/10/17/solution-for-stack-and-minimum-element-in-o1/

《微软面试100题 In Java》02.Stack and minimum element in O(1),布布扣,bubuko.com

《微软面试100题 In Java》02.Stack and minimum element in O(1)

原文:http://blog.csdn.net/speedme/article/details/20716727

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!