给定一个int[] numbers(C++中为vector<int>),其中第一个元素为栈顶,请编写程序将栈进行升序排列(即最大元素位于栈顶),返回排序后的栈。要求最多使用一个额外的栈存放临时数据,但不得将元素复制到别的数据结构中。并注意这是一个栈,意味着排序过程中只能访问到最后一个元素。
测试样例:
[1,2,3,4,5]
返回:[5,4,3,2,1]
public ArrayList<Integer> twoStacksSort(int[] numbers) { // write code here ArrayList<Integer> result = new ArrayList<>(); if(numbers.length == 0){ return result; } Stack<Integer> tmp = new Stack<>(); Stack<Integer> help = new Stack<>(); for (int i = 0; i< numbers .length; i++){ tmp.push(numbers[i]); } while(tmp.size() != 0){ int num = tmp.pop(); if (help.size() == 0 || help.peek() <= num){ help.push(num); }else { tmp.push(help.pop()); tmp.push(num);//复原 } } while(help.size() != 0){ result.add(help.pop()); } return result; }
时间
O(N^2)
import java.util.*;
public class TwoStacks {
public ArrayList<Integer> twoStacksSort(int[] numbers) {
ArrayList<Integer> res = new ArrayList<Integer>();
if (numbers.length == 0) return res;
stackA意在存数
Stack<Integer> stackA = new Stack<Integer>();
for(int n: numbers) stackA.push(n);
stackB意在存升序
Stack<Integer> stackB = new Stack<Integer>();
stackB.push(stackA.pop());
while(!stackA.isEmpty()) {
int a = stackA.pop();
如果stackB里面有比当前小的数,就扔回去stackA
while(!stackB.isEmpty() && a < stackB.peek()){
stackA.push(stackB.pop());
}
stackB.push(a);
}
while(!stackB.isEmpty()){
res.add(stackB.pop());
}
return res;
}
}
//构建一个辅助栈存放排好序的 和 一个变量存放临时值
public ArrayList<Integer> twoStacksSort(int[] numbers) {
ArrayList<Integer> res = new ArrayList<>();
if (numbers == null || numbers.length == 0) return res;
Stack<Integer> stack1 = new Stack<>();//原始栈
for (int i = numbers.length - 1; i >= 0; i--)
stack1.push(numbers[i]);
int temp;//存放临时值
Stack<Integer> stack2 = new Stack<>();
while (stack1.size() != 0) {
temp = stack1.pop();
while (stack2.size() != 0 && stack2.peek() > temp) {//辅助栈不为空,且栈头元素比临时值大
stack1.push(stack2.pop());
}
stack2.push(temp);
}
while (stack2.size() != 0) {
res.add(stack2.pop());
}
return res;
}
while(top<numbers.length){
}
import java.util.*; public class TwoStacks { public ArrayList<Integer> twoStacksSort(int[] numbers) { // write code here ArrayList<Integer> result = new ArrayList<Integer>(); Stack<Integer> stack = new Stack<Integer>(); int n = numbers.length - 1; while (n >= 0) { stack.push(numbers[n]); n--; } while (!stack.isEmpty()) { int tmp = stack.pop(); while (result.size() != 0 && result.get(result.size() - 1) < tmp) { stack.push(result.remove(result.size() - 1)); } result.add(tmp); } return result; } }
1.设置两个栈,一个保存结果,一个用来临时存放数据进行比较 2.当结果栈空或栈的第一个数据小于要插入的数据时直接插入 3.当结果栈不是空的时候,取出栈顶放入临时栈 4.循环2,3步骤直到数据插入 5.把临时栈的数据按序插入回结果栈
public class TwoStacks { public ArrayList<Integer> twoStacksSort(int[] numbers) { // write code here ArrayList<Integer> result = new ArrayList<Integer>(); ArrayList<Integer> temp = new ArrayList<Integer>(); for(int i=0;i<numbers.length;i++){ if(result.isEmpty()) result.add(numbers[i]); else{ while(!result.isEmpty()&&result.get(0)>numbers[i]){ temp.add(0,result.remove(0)); } result.add(0,numbers[i]); while(!temp.isEmpty()){ result.add(0,temp.remove(0)); } } } return result; } }
//看到题目蛋碎一地,说好的是栈,你给我一个数组是什么意思,人与人之间最基本的信任呢 //还只让我用一个额外栈,结果输出是个ArrayList,如果照题目意思把ArrayList也当成一个栈。。。那还要啥自行车 //我的内心是崩溃的,然后就有了这样的写法 //思路,取出栈1中元素放在栈2中,然后栈1再弹出一个元素,比较这个元素与栈2顶元素大小,如果大于等于栈二顶元素,就把它压入栈2中,如果小于,就把栈2中元素弹出一个压入栈1中,重复比较,直到元素大于栈2顶元素或栈2为空,就把它压入栈2中,实现排序。 //方法一: public ArrayList<Integer> twoStacksSort(int[] numbers) { ArrayList<Integer> result=new ArrayList<Integer>(); if(numbers==null) return result; int count=0,temp=0,index=0; while(index<numbers.length){ temp=count==0?numbers[index++]:temp; if(result.size()==0||temp>=result.get(0)){ result.add(0,temp); // while(count-->0) result.add(0,numbers[index++]);//这句话可以不要 count=0; } else { numbers[--index]=result.remove(0); count++; } } return result; } //方法二,原理同方法一,不让我用栈我偏用,我是菜鸟我怕谁QAQ public ArrayList<Integer> twoStacksSort(int[] numbers) { ArrayList<Integer> result=new ArrayList<Integer>(); if(numbers==null) return result; Stack<Integer> stack= new Stack<Integer>(); Stack<Integer> resultStack= new Stack<Integer>(); for(int i=0;i<numbers.length;i++) stack.push(numbers[numbers.length-i-1]); int count=0,temp=0; while(!stack.isEmpty()){ temp=count==0?stack.pop():temp; if(resultStack.isEmpty()||temp>=resultStack.peek()){ resultStack.push(temp); // while(count-->0) resultStack.push(stack.pop());//这句话可以不要,不过不知道为什么加上这句话,运行占用内存是1000多K,不加是3000多K count=0; } else { stack.push(resultStack.pop()); count++; } } while(!resultStack.isEmpty()) result.add(resultStack.pop()); return result; }
public class TwoStacks { public ArrayList<Integer> twoStacksSort(int[] numbers) { //首先判断传过来的数组是否为空, if(numbers==null||numbers.length==0){ return null; } //创建需要的量 /*(1) * 用于返回的链表 * (2)两个栈 * (3)用于储存buffer部分栈顶的临时变量bufTop * */ ArrayList<Integer> res=new ArrayList<Integer>(); Stack<Integer> buffer=new Stack<Integer>(); Stack<Integer> asc=new Stack<Integer>(); int bufTop=0; //buffer栈装入numbers的数字(这里留了一个未装) for(int i=0;i<numbers.length-1;i++){ buffer.push(numbers[i]); } //留下的那一个装给asc asc.push(numbers[numbers.length-1]); /*如果buffer栈顶元素a>=asc栈顶元素,则直接把buffer的栈顶元素装入asc 否则,把buffer的栈顶元素a出栈,并装入临时变量bufTop,然后把asc的栈顶进行出栈并装入buffer, 直到bufTop<asc的栈顶元素,才把bufTop装入asc并把之前从asc已经出栈的元素全部压入asc, 不断循环,直到buffer为空 */ //设置一个变量,用于标记buffer的初始长度 int bufSize=0; while(buffer.size()>0){ //如果buffer栈顶大于等于asc栈顶,则直接把buffer的栈顶元素出栈,并压入到asc中 if(buffer.peek()>=asc.peek()){ asc.push(buffer.pop()); }else{ bufTop=buffer.pop(); //记录初始长度 bufSize=buffer.size(); while(!asc.isEmpty()&&bufTop<asc.peek()){ buffer.push(asc.pop()); } //一旦bufTop小于了asc的栈顶,就立即装入bufTop asc.push(bufTop); //此时计算buffer中压入了多少asc的元素 int countFromAsce=buffer.size()-bufSize; //把从asc中得到的元素全部返还asc for(int j=1;j<=countFromAsce;j++){ asc.push(buffer.pop()); } } } //返还排好序的链表 while(asc.size()>0){ System.out.println(asc.peek()); res.add(asc.pop()); } return res; }
//一个结果栈,一个辅助栈,保持结果栈的数据都要大于辅助栈的数据,并且结果栈升序,辅助栈降序 //Arraylist 竟然是0作为栈顶,有点晕 import java.util.*; public class TwoStacks { public ArrayList<Integer> twoStacksSort(int[] numbers) { ArrayList<Integer> res=new ArrayList<Integer>(); ArrayList<Integer> tmp=new ArrayList<Integer>(); for(int i=0;i<numbers.length;i++){ while(res.size()>0&&numbers[i]<res.get(0)) tmp.add(0,res.remove(0)); while(tmp.size()>0&&numbers[i]>tmp.get(0)) res.add(0,tmp.remove(0)); res.add(0,numbers[i]); } while(tmp.size()>0) res.add(0,tmp.remove(0)); return res; } }
}
import java.util.*; public class TwoStacks { public ArrayList<Integer> twoStacksSort(int[] numbers) { if(numbers==null || numbers.length<=0){ return null; } ArrayList<Integer> resultStack = new ArrayList<Integer>(numbers.length); //构建额外的栈 Stack<Integer> stack = new Stack<Integer>(); for(int i=numbers.length-1;i>=0;i--){ stack.push(numbers[i]); } //排序添加至数组链表,因链表头表示栈顶,所以应调用add(0,num)方法 while(!stack.empty()){ if(resultStack.size()==0){ resultStack.add(0,stack.pop()); }else{ int a = stack.pop(); int b = resultStack.remove(0); if(a<b){ stack.push(b); while(resultStack.size()>0 && a<(b = resultStack.remove(0))){ stack.push(b); } } if(a>=b){ resultStack.add(0,b); } resultStack.add(0,a); } } //返回的数组链表的第一个元素为栈顶 return resultStack; } }
import java.util.*; public class TwoStacks { public ArrayList<Integer> twoStacksSort(int[] numbers) { // write code here ArrayDeque<Integer> stack = new ArrayDeque<Integer>(); for (int i = numbers.length - 1; i >= 0; i --) { stack.push(numbers[i]); } ArrayDeque<Integer> sortStack = new ArrayDeque<Integer>(); while (!stack.isEmpty()) { int num = stack.pop(); if (sortStack.isEmpty()) { sortStack.push(num); continue; } while (!sortStack.isEmpty() && sortStack.peek() > num) { stack.push(sortStack.pop()); } sortStack.push(num); } ArrayList<Integer> res = new ArrayList<Integer>(); while (!sortStack.isEmpty()) { res.add(sortStack.pop()); } return res; } }