论坛首页 综合技术论坛

百度一面算法题(常数时间内求栈中最大值)

浏览 24962 次
精华帖 (0) :: 良好帖 (3) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-11-04  
tswwz 写道
可以考虑与当前stack维护对应的代表stack对应位置的最大值的栈MaxStack

对于栈stack

push元素 valueA时
           maxValue = popMaxStack();  pushMaxStack(maxValue);

           if  (valueA >= maxValue)   pushStack(valueA) ; pushMaxStack(valueA);
           if  (valueA < maxValue)    pushStack(valueA) ; pushMaxStack(maxValue);

pop元素
           maxValue = popMaxStack();  pushMaxStack(maxValue);
           valueA = popStack();
           popMaxStack();


这样取最大值时,直接  maxValue = popMaxStack();pushMaxStack(maxValue);就ok了。

我的作法是popStack()的元素valueA与popMaxStack()的元素maxValue得比较一下.
若相等(表明弹出的元素是当前最大的那个元素),则不做任何操作;
若不相等(表明弹出的元素不是当前最大的那个元素),则再做pushMaxStack(maxValue)操作.
0 请登录后投票
   发表时间:2011-11-04  
yeshaoting 写道

 


算法描述:

一个栈stack,具有push和pop操作,其时间复杂度皆为O(1)。

设计算法max操作,求栈中的最大值,该操作的时间复杂度也要求为O(1)。

可以修改栈的存储方式,push,pop的操作,但是要保证O(1)的时间复杂度,空间时间复杂度无要求。


思路:

我借助一个变量count和一个数组空间(其实就是一个栈)完成该时间复杂度为O(1)的算法设计。

 

 

这里面不需要用到快排吧。。那样的话还能叫o(1)?

贴上我的code:用了个最大栈保存添加路径上的最大值,删除的时候如果相等撤销最大值栈中的顶部元素即可。

 

另鄙视下,共享东西的时候都鼓掌叫好,求助发问就隐藏哦鄙视哦扣分哦臭鸡蛋烂白菜都来了。。。不多说了 果断以后文章只丢博客里

 

package sunfa;

import java.util.Arrays;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.Random;

public class LinkedListMaxVal<E> {
	public static void main(String[] args) {
		LinkedListMaxVal<Integer> stack = new LinkedListMaxVal<Integer>(
				new Comparator<Integer>() {
					public int compare(Integer o1, Integer o2) {
						return o1 - o2;
					}
				});
		Random ran = new Random();
		for (int i = 1; i <= 20; i++) {
			stack.push(ran.nextInt(100));
			System.out.println(stack + "," + stack.max()+","+stack.maxStack);
			if (i % 4 == 0) {
				Integer ee = stack.peek();
				System.out.println("=============>pop:"+ee+"," + stack + "," + stack.max()+","+stack.maxStack);
				stack.pop();
			}
		}
		System.out.println("pop all>>>>>>>>>>>>>------------------");
		System.out.println("删除的元素  | 数据栈   |  最大值  |  最大值栈");
		while(!stack.isEmpty()){
			Integer ee = stack.peek();
			System.out.println("pop:" +ee+","+ stack + "," + stack.max()+","+stack.maxStack);
			stack.pop();
		}
		System.out.println("---end-----");
		System.out.println(stack);
	}

	private Object[] item;
	private int count;//栈内元素数目    ,栈顶元素索引为count-1
	private LinkedList<E> maxStack = new LinkedList<E>();//最大值备用栈,为省事借用链表
	private final String EMPTY_STACK_STR = "空栈";
	private Comparator<E> comp;

	public LinkedListMaxVal(Comparator<E> c) {
		item = new Object[10];
		comp = c;
	}

	public void push(E e) {
		if (e == null)
			throw new NullPointerException();
		if (count + 1 == item.length)
			item = Arrays.copyOf(item, item.length << 1);
		item[count++] = e;

		if (count == 1)
			maxStack.push(e);
		else {
			if (compare(maxStack.peekFirst(), e) <= 0)//=号不要丢了,这很关键
				maxStack.push(e);
		}
	}

	public E pop() {
		if (isEmpty())
			throw new NullPointerException(EMPTY_STACK_STR);
		E e = peek();
		item[count - 1] = null;

		if (count == 1) 
			maxStack.pop();
		 else {
			if (compare(maxStack.peekFirst(), e) == 0)
				maxStack.pop();
		}

		count--;
		return e;
	}

	public E max() {
		if (maxStack.isEmpty())
			throw new NullPointerException(EMPTY_STACK_STR);
		return maxStack.peekFirst();
	}

	public E peek() {
		if (isEmpty())
			throw new NullPointerException(EMPTY_STACK_STR);
		return (E) item[count - 1];
	}

	private int compare(E e1, E e2) {
		return comp != null ? (((comp).compare(e1, e2)))
				: (((Comparable<E>) e1).compareTo(e2));
	}

	public boolean isEmpty() {
		return count == 0;
	}

	public String toString() {
		String s = "[";
		for (int i = 0; i < item.length; i++) {
			if (item[i] != null)
				s += item[i] + ",";
		}
		if (s.length() == 1) {
			s += "]";
		} else {
			s = s.substring(0, s.length() - 1) + "]";
		}
		return s;
	}
}
 
1 请登录后投票
   发表时间:2011-11-05  
543089122 写道
yeshaoting 写道

 

 


算法描述:

一个栈stack,具有push和pop操作,其时间复杂度皆为O(1)。

设计算法max操作,求栈中的最大值,该操作的时间复杂度也要求为O(1)。

可以修改栈的存储方式,push,pop的操作,但是要保证O(1)的时间复杂度,空间时间复杂度无要求。


思路:

我借助一个变量count和一个数组空间(其实就是一个栈)完成该时间复杂度为O(1)的算法设计。

 

 

这里面不需要用到快排吧。。那样的话还能叫o(1)?

贴上我的code:用了个最大栈保存添加路径上的最大值,删除的时候如果相等撤销最大值栈中的顶部元素即可。

 

是不需要用到快排.

之前贴上代码的仁兄,是用快排求栈中所有数据的中间值.对于求最大值和最小值跟你的过程是一样的.

 

思路和代码写得挺好的.投你一票了.

0 请登录后投票
   发表时间:2011-11-05  
yeshaoting 写道
tswwz 写道
可以考虑与当前stack维护对应的代表stack对应位置的最大值的栈MaxStack

对于栈stack

push元素 valueA时
           maxValue = popMaxStack();  pushMaxStack(maxValue);

           if  (valueA >= maxValue)   pushStack(valueA) ; pushMaxStack(valueA);
           if  (valueA < maxValue)    pushStack(valueA) ; pushMaxStack(maxValue);

pop元素
           maxValue = popMaxStack();  pushMaxStack(maxValue);
           valueA = popStack();
           popMaxStack();


这样取最大值时,直接  maxValue = popMaxStack();pushMaxStack(maxValue);就ok了。

确实是有额外用到一个栈空间.
我的push元素想法跟你一样.
但是没太看懂你的pop元素.




其实就是出栈。。。。  popStack();popMaxStack(); 
        
maxValue = popMaxStack();  pushMaxStack(maxValue);  这个只是说明取最大值的方法,没啥意义,估计误导人了。
         
0 请登录后投票
   发表时间:2011-11-06  
yeshaoting 写道
543089122 写道
yeshaoting 写道

 

 


算法描述:

一个栈stack,具有push和pop操作,其时间复杂度皆为O(1)。

设计算法max操作,求栈中的最大值,该操作的时间复杂度也要求为O(1)。

可以修改栈的存储方式,push,pop的操作,但是要保证O(1)的时间复杂度,空间时间复杂度无要求。


思路:

我借助一个变量count和一个数组空间(其实就是一个栈)完成该时间复杂度为O(1)的算法设计。

 

 

这里面不需要用到快排吧。。那样的话还能叫o(1)?

贴上我的code:用了个最大栈保存添加路径上的最大值,删除的时候如果相等撤销最大值栈中的顶部元素即可。

 

是不需要用到快排.

之前贴上代码的仁兄,是用快排求栈中所有数据的中间值.对于求最大值和最小值跟你的过程是一样的.

 

思路和代码写得挺好的.投你一票了.

543089122:求中位数使用快速排序并不是最高效的算法,肯定有比快速更高效的算法,如果你有什么好的思路也可以分享一下,谢谢!

 

0 请登录后投票
   发表时间:2011-11-07  
没咋看明白。栈顶上压一个代表max的值不行么?一弹弹出俩,按需修改,压回俩。也算O(1) 吧
0 请登录后投票
   发表时间:2011-11-08  
EldonReturn 写道
没咋看明白。栈顶上压一个代表max的值不行么?一弹弹出俩,按需修改,压回俩。也算O(1) 吧

这样是不行的.
倘若即将弹出的那个值等于当前max的值当如何???
0 请登录后投票
   发表时间:2011-11-08  
yeshaoting 写道
YuHuang.Neil 写道
我的实现是



import java.util.ArrayList;
import java.util.EmptyStackException;
import java.lang.NullPointerException;

public class StackForPriorImpl<E extends Comparable<E>> implements
IStackForPrior<E> {

private int numberOfObject;
private ArrayList<E> dataForOrginal;
private ArrayList<E> dataForMaximun;
private ArrayList<E> dataForMinimun;
private E maxElement;
private E minElement;

public StackForPriorImpl(){
this.numberOfObject = 0;
this.dataForOrginal = new ArrayList<E>();
this.dataForMaximun = new ArrayList<E>();
this.dataForMinimun = new ArrayList<E>();
}

@Override
public void push(E e) {

if(e==null){
throw new NullPointerException();
}

dataForOrginal.add(e);

if(numberOfObject==0){
maxElement = e;
minElement = e;
this.dataForMaximun.add(maxElement);
this.dataForMinimun.add(minElement);
}else{

if(e.compareTo(maxElement)>0){
dataForMaximun.add(e);
maxElement = e;
}else{
dataForMaximun.add(maxElement);
}

if(e.compareTo(minElement)<0){
dataForMinimun.add(e);
minElement = e;
}else{
dataForMinimun.add(minElement);
}
}

++numberOfObject;

}

@Override
public E pop() {

if(numberOfObject==0) {
throw new EmptyStackException();
}

int index = --numberOfObject;

dataForMaximun.remove(index);
maxElement = dataForMaximun.get(index-1);

dataForMinimun.remove(index);
minElement = dataForMinimun.get(index-1);

E e = dataForOrginal.get(index);
dataForOrginal.remove(index);
return e;
}

@Override
public E peekMedian() {

if(numberOfObject==0){
throw new EmptyStackException();
}

Object[] elementArray=this.dataForOrginal.toArray();
int lengthOfElementArray = elementArray.length;
quickSort(elementArray,0,lengthOfElementArray-1);

return (E)elementArray[lengthOfElementArray/2];
}

@Override
public E peekMaximum() {

if(numberOfObject==0){
throw new EmptyStackException();
}

int index = numberOfObject - 1;
return this.dataForMaximun.get(index);
}

@Override
public E peekMinimum() {

if(numberOfObject==0) {
throw new EmptyStackException();
}

int index = numberOfObject - 1;
return this.dataForMinimun.get(index);
}

@Override
public int size() {

return this.numberOfObject;
}

private static <E> void quickSort(E[] elementArray,int low,int high){
if(low<high){
int q = partition(elementArray,low,high);
quickSort(elementArray,low,q-1);
quickSort(elementArray,q+1,high);
}
}

private static <E> int partition(E[] elementArray,int low,int high){
int i = low, j=high+1;
E e= elementArray[low];
while(true){
while(elementArray[++i].toString().compareTo(e.toString())<0 && i<high);
while(elementArray[--j].toString().compareTo(e.toString())>0);
if(i>=j) break;

E temp = elementArray[i];
elementArray[i]=elementArray[j];
elementArray[j]=temp;
}

elementArray[low] = elementArray[j];
elementArray[j]=e;

return j;
}

public static void main(String[] args){
StackForPriorImpl<Integer> stack=new StackForPriorImpl<Integer>();

stack.push(new Integer(2));
stack.push(new Integer(1));
stack.push(new Integer(2));
stack.push(new Integer(2));
stack.push(new Integer(6));
stack.push(new Integer(4));
stack.push(new Integer(2));
stack.push(new Integer(5));

System.out.println("size = "+stack.size());
System.out.println("peekMaximun = "+stack.peekMaximum().toString());
System.out.println("peekMinimun = "+stack.peekMinimum().toString());
System.out.println("peekMedian = "+stack.peekMedian().toString());

}
}

写得很好~~
跟我当时的做法是一样的.


好扯,找个代码你pop掉一个以后在看结果,还是6...
0 请登录后投票
   发表时间:2011-11-08  
lzyzizi 写道
yeshaoting 写道
YuHuang.Neil 写道
我的实现是



import java.util.ArrayList;
import java.util.EmptyStackException;
import java.lang.NullPointerException;

public class StackForPriorImpl<E extends Comparable<E>> implements
IStackForPrior<E> {

private int numberOfObject;
private ArrayList<E> dataForOrginal;
private ArrayList<E> dataForMaximun;
private ArrayList<E> dataForMinimun;
private E maxElement;
private E minElement;

public StackForPriorImpl(){
this.numberOfObject = 0;
this.dataForOrginal = new ArrayList<E>();
this.dataForMaximun = new ArrayList<E>();
this.dataForMinimun = new ArrayList<E>();
}

@Override
public void push(E e) {

if(e==null){
throw new NullPointerException();
}

dataForOrginal.add(e);

if(numberOfObject==0){
maxElement = e;
minElement = e;
this.dataForMaximun.add(maxElement);
this.dataForMinimun.add(minElement);
}else{

if(e.compareTo(maxElement)>0){
dataForMaximun.add(e);
maxElement = e;
}else{
dataForMaximun.add(maxElement);
}

if(e.compareTo(minElement)<0){
dataForMinimun.add(e);
minElement = e;
}else{
dataForMinimun.add(minElement);
}
}

++numberOfObject;

}

@Override
public E pop() {

if(numberOfObject==0) {
throw new EmptyStackException();
}

int index = --numberOfObject;

dataForMaximun.remove(index);
maxElement = dataForMaximun.get(index-1);

dataForMinimun.remove(index);
minElement = dataForMinimun.get(index-1);

E e = dataForOrginal.get(index);
dataForOrginal.remove(index);
return e;
}

@Override
public E peekMedian() {

if(numberOfObject==0){
throw new EmptyStackException();
}

Object[] elementArray=this.dataForOrginal.toArray();
int lengthOfElementArray = elementArray.length;
quickSort(elementArray,0,lengthOfElementArray-1);

return (E)elementArray[lengthOfElementArray/2];
}

@Override
public E peekMaximum() {

if(numberOfObject==0){
throw new EmptyStackException();
}

int index = numberOfObject - 1;
return this.dataForMaximun.get(index);
}

@Override
public E peekMinimum() {

if(numberOfObject==0) {
throw new EmptyStackException();
}

int index = numberOfObject - 1;
return this.dataForMinimun.get(index);
}

@Override
public int size() {

return this.numberOfObject;
}

private static <E> void quickSort(E[] elementArray,int low,int high){
if(low<high){
int q = partition(elementArray,low,high);
quickSort(elementArray,low,q-1);
quickSort(elementArray,q+1,high);
}
}

private static <E> int partition(E[] elementArray,int low,int high){
int i = low, j=high+1;
E e= elementArray[low];
while(true){
while(elementArray[++i].toString().compareTo(e.toString())<0 && i<high);
while(elementArray[--j].toString().compareTo(e.toString())>0);
if(i>=j) break;

E temp = elementArray[i];
elementArray[i]=elementArray[j];
elementArray[j]=temp;
}

elementArray[low] = elementArray[j];
elementArray[j]=e;

return j;
}

public static void main(String[] args){
StackForPriorImpl<Integer> stack=new StackForPriorImpl<Integer>();

stack.push(new Integer(2));
stack.push(new Integer(1));
stack.push(new Integer(2));
stack.push(new Integer(2));
stack.push(new Integer(6));
stack.push(new Integer(4));
stack.push(new Integer(2));
stack.push(new Integer(5));

System.out.println("size = "+stack.size());
System.out.println("peekMaximun = "+stack.peekMaximum().toString());
System.out.println("peekMinimun = "+stack.peekMinimum().toString());
System.out.println("peekMedian = "+stack.peekMedian().toString());

}
}

写得很好~~
跟我当时的做法是一样的.


好扯,找个代码你pop掉一个以后在看结果,还是6...

没太看懂的意思....
这个程序我觉得写得没有问题呀.
期待你的高见.
0 请登录后投票
   发表时间:2011-11-08  
做一链状列表;
push的时候 链表插入元素,并保持链表降序排列;
pup的时候直接在链表种找到结点删除即可。
链表第一个结点始终为栈中元素最大值。

0 请登录后投票
论坛首页 综合技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics