关于模拟盘子的堆栈实现(Crack the interview 例题)之暑假学习记录

来源:互联网 发布:hadoop编译java文件 编辑:程序博客网 时间:2024/06/07 10:50

这两天,可能运动量过大,每天很是昏昏沉沉。今天写一个例题程序,自以为很容易就搞定,没想到墨墨迹迹搞了一个多小时。可见精神状态也很重要,但同时也发现了一些自己关于java的问题。这篇文章只为记录今天垃圾的状态,如果有朋友有兴趣去看这道题目,可以拿走。

题目大致是这样的:

模拟实现一组盘子,盘子的原理就是堆栈原理,那么为了不使盘子因过高而摔碎,我们可以给盘子分组,每一组是N个。但是拿取盘子的方式还是按照堆栈的方式实现,即先进后出(FILO)。 这道题目的有意思之处在于,如何在指定的分组中用FILO的方式取盘子并且保证盘子序号左对齐。(这句主要我不知道怎么翻译好,给大家举个例子就明白了)

分组1:a, b, c 

分组2:d, e, f

分组3: g, h ,i

如果从分组1中pop一个元素,那么整个分组变成:

分组1:a, b, d 

分组2:e, f, g

分组3: h ,i

如果分组一直在分组1中pop的话,那么分组3可能会成一个空元素分组,那么删除此分组。

看到这里大家估计都有想法了,是的,这个不难。但是我的思路可能不够精妙,如果大家有新的建议,欢迎留言。

1. 题目分析:

思路1:如果把每个分组严格按照栈去操作,FILO,可以搞定。但是时间复杂度太大。因为每个元素的pop都需要移动n个元素,非常耗时。

思路2:如果把分组当作队列处理,是不是就可以满足这类操作呢?是的,但是这破坏了本身分组操作的手段。在我们push的时候,方便,在pop的时候就麻烦了。

思路3:把这个当作栈,但是用链表实现,基本操作还是FILO,但是在指定分组pop的操作,用队列的原理实现。这并不违背堆栈的操作意义。而下面代码就是根据这种思想写的。这样的话每次pop操作的时间复杂度在O(1),完全达到要求。

废话不多说,上代码:

import java.util.LinkedList;public class SetsOfStack3 {LinkedList<Stack> s;int capacity;public SetsOfStack3(int num){s = new LinkedList<Stack>();s.add(new Stack());this.capacity = num;}public void push(int value){Stack last = s.getLast();if(last!=null && last.size() < this.capacity){last.push(value);}else{s.add(new Stack());s.getLast().push(value);}}public int pop(){int value = 0;Stack last = s.getLast();value = last.pop();if(last.size() == 0)s.removeLast();return value;}public static void printStack1s(LinkedList<Stack> list){System.out.println("--------------------------------------");for(int i = 0; i<list.size();i++){System.out.println("Stack"+(i+1)+" is : ");for(int j=0;j<list.get(i).size();j++){System.out.print(list.get(i).get(j)+ " ");}System.out.println();}System.out.println("\n--------------------------------------");}public int popAt(int index){int value = 0;if(index >= s.size()){System.out.println("Non-existed index");return -1;}else if(index + 1 >= s.size()){value = this.pop();}else{Stack current = s.get(index);Stack next = current;value = current.pop();while(++index < s.size()){next = s.get(index);current.rollOver(next);current = next;if(s.getLast().size() == 0 )s.removeLast();}}return value;}public static void main(String[] args){SetsOfStack3 s = new SetsOfStack3(3);s.push(1);s.push(2);s.push(3);s.push(4);s.push(5);s.push(6);s.push(7);s.push(8);s.push(9);s.push(10);s.push(15);s.push(20);printStack1s(s.s);System.out.println("pop at 1: "+s.popAt(0));printStack1s(s.s);System.out.println("pop at 2: "+s.popAt(1));printStack1s(s.s);System.out.println("pop at 2: "+s.popAt(1));printStack1s(s.s);}} class Stack{LinkedList<Integer> list;public Stack(){list = new LinkedList<Integer>();}void push(int value){list.add(value);}int pop(){return list.removeLast();}int size(){return list.size();}int getFirst(){return list.getFirst();}int getLast(){return list.getLast();}int pollFirst(){return list.poll(); }int get(int index){return list.get(index);}void rollOver(Stack test){ list.add(test.pollFirst());}}


这个代码是在我调试version1的代码一个小时后,愤怒删除后,从新start from scratch 写的,效果不错。这证明当思路紊乱的时候,打碎重写不失为一种好办法。

为了忘却而纪念今天的垃圾状态。阿弥陀佛上帝保佑阿门阿门。