这两天,可能运动量过大,每天很是昏昏沉沉。今天写一个例题程序,自以为很容易就搞定,没想到墨墨迹迹搞了一个多小时。可见精神状态也很重要,但同时也发现了一些自己关于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 写的,效果不错。这证明当思路紊乱的时候,打碎重写不失为一种好办法。
为了忘却而纪念今天的垃圾状态。阿弥陀佛上帝保佑阿门阿门。