请设计一种方法将一个栈进行升序排列 (最大的数在最上面)。
你可以使用另外一个栈来辅助操作,但不可将这些数复制到另外一个数据结构中 (如,数组)。
样例
给一个栈:
| |
|3|
|1|
|2|
|4|
-
排序之后:
| |
|4|
|3|
|2|
|1|
-
栈会被序列化为[4,2,1,3]
,也就是说最右边是栈顶。
注意事项
时间复杂度为O(n^2)的算法也可以通过测试
解题思路:
类似于汉诺塔问题。利用两个栈倒来倒去,最终完成排序。
- 把原stack1的数push到另一个stack2中,push的原则是大的数在下面,如果遇到要push的值比stack2的top大的话,就把stack1要push的值先暂存为num,然后将stack2的值pop出来,放到stack1中,直到要push进去的数num是stack2目前最小的。按这样循环直至stack1为空。
- 把stack2的数按顺序push到stack1中,直到stack2为空。此时stack1中的数就是排好序的。
public class Solution {
/*
* @param stk: an integer stack
* @return: void
*/
public void stackSorting(Stack<Integer> stack) {
// write your code here
Stack<Integer> temp = new Stack<>();
while(!stack.isEmpty()){
//temp最终的目的是从栈底到栈顶降序
//所以当temp.peek() >= stack.peek(),直接push进temp
while(!stack.isEmpty() && (temp.isEmpty() || stack.peek() <= temp.peek()))
temp.push(stack.pop());
//说明temp.peek() < stack.peek(),要维持temp的性质,就不能直接插入
//需要将stack.pop出来暂存,然后将temp中所有小于此数的值全部pop出来进入stack
//执行后此时temp.peek() >= num,依然保持性质,将num push进temp,再循环
if(!stack.isEmpty()){
int num = stack.pop();
while(!temp.isEmpty() && temp.peek() < num)
stack.push(temp.pop());
temp.push(num);
}
}
//最后将temp倒进stack中,即为升序
while(!temp.isEmpty())
stack.push(temp.pop());
}
}
二刷:
public class Solution {
/*
* @param stk: an integer stack
* @return: void
*/
public void stackSorting(Stack<Integer> stk) {
// write your code here
Stack<Integer> stk1 = new Stack<>();
while(!stk.isEmpty()){
if(stk1.isEmpty() || stk1.peek() >= stk.peek()){
stk1.push(stk.pop());
}else{
int temp = stk.pop();
while(!stk1.isEmpty() && stk1.peek() < temp)
stk.push(stk1.pop());
stk1.push(temp);
}
}
while(!stk1.isEmpty())
stk.push(stk1.pop());
}
}