给你一个 1 到 n 的排列和一个栈,并按照排列顺序入栈
你要在不打乱入栈顺序的情况下,仅利用入栈和出栈两种操作,输出字典序最大的出栈序列
排列:指 1 到 n 每个数字出现且仅出现一次
数据范围:
,排列中的值都满足
进阶:空间复杂度
,时间复杂度
[2,1,5,3,4]
[5,4,3,1,2]
操作 栈 结果 2 入栈;[2] [] 1 入栈;[2\1] [] 5 入栈;[2\1\5] [] 5 出栈;[2\1] [5] 3 入栈;[2\1\3] [5] 4 入栈;[2\1\3\4] [5] 4 出栈;[2\1\3] [5,4] 3 出栈;[2\1] [5,4,3] 1 出栈;[2] [5,4,3,1] 2 出栈;[] [5,4,3,1,2]
[1,2,3,4,5]
[5,4,3,2,1]
class Solution {
public:
/**
* 栈排序
* @param a int整型一维数组 描述入栈顺序
* @param aLen int a数组长度
* @return int整型vector
*/
vector<int> solve(int* a, int aLen) {
// write code here
int j=0, n=aLen;
vector<vector<int>> mr(n, vector<int>(2, 0));
int Max = INT_MIN;
for(int i=n-1; i>=0; i--) {
if(Max<a[i]) {
Max = a[i];
j = i;
}
mr[i][0] = Max;
mr[i][1] = j;
}
stack<int> st;
vector<int> ans;
for(int i=0; i<n; i++) {
st.push(a[i]);
if(i==mr[i][1]) {
ans.push_back(st.top());
st.pop();
while(!st.empty() && i<n-1 && st.top()>mr[i+1][0]) {
ans.push_back(st.top());
st.pop();
}
}
}
while(!st.empty()) {
ans.push_back(st.top());
st.pop();
}
return ans;
}
}; public int[] solve (int[] a) {
int n=a.length;
Stack<Integer>stack=new Stack<>();
int[]dp=new int[n];
dp[n-1]=a[n-1];
for(int i=n-2;i>=0;i--)
dp[i]=Math.max(dp[i+1],a[i]); //用一个数组记录第i个及之后最大元素
int[]res=new int[n];
int j=0;
for(int i=0;i<n;i++){
stack.push(a[i]);
while(!stack.isEmpty()&&i<n-1&&stack.peek()>=dp[i+1])
res[j++]=stack.pop();//如果栈顶元素比后面的都大,那么出栈
}
while(!stack.isEmpty()) res[j++]=stack.pop(); //最后在栈中的按顺序弹出
return res;
} public int[] solve (int[] a) {
// write code here
int[] res = new int[a.length];
int pos = 0;
Stack<Integer> indexStack = new Stack<>();
Stack<Integer> helperStack = new Stack<>();
// 构建单调栈,栈中存储元素下标,元素值单调递增
for (int i = 0; i < a.length; i++) {
while (!indexStack.isEmpty() &&
a[indexStack.peek()] > a[i]) helperStack.push(indexStack.pop());
indexStack.push(i);
while (!helperStack.isEmpty()) indexStack.push(helperStack.pop());
}
// 开始未弹栈的全局最大值,通过单调栈可以直接获取
// 只有当当前值出现在最大值右侧时,才可以开始弹栈,否则最大值仍未出现,即使递减也不能立即弹栈
ArrayList<Integer> firstPopList = new ArrayList<>();
for (int i = 0; i < a.length; i++) {
while (!indexStack.isEmpty() && indexStack.peek() <= i &&
a[indexStack.peek()] >= a[i]) {
// 弹出到i的全局最大值,并继续寻找,直到循环退出
Integer pop = indexStack.pop();
firstPopList.add(pop);
// 找出待弹出元素的真实索引顺序,同样只用栈实现
if (helperStack.isEmpty() || helperStack.peek() >= pop)
helperStack.push(pop);
else {
// 使用 helperStack 排序,辅助栈 tmpStack
Stack<Integer> tmpStack = new Stack<>();
while (helperStack.peek() < pop) tmpStack.push(helperStack.pop());
helperStack.push(pop);
while (!tmpStack.isEmpty()) helperStack.push(tmpStack.pop());
}
}
// 将正确的顺序的元素填充到结果表
while (!helperStack.isEmpty())res[pos++] = a[helperStack.pop()];
}
// 剩余的元素填充
if (!indexStack.isEmpty() && !firstPopList.isEmpty()) {
for (int i = a.length - 1; i >= 0; i--)
if (!firstPopList.contains(i)) res[pos++] = a[i];
}
return res;
} public int[] solve (int[] a) {
int len = a.length, pos = 0;
Stack<Integer>stack = new Stack<>();
int[] res = new int[a.length];
int[]dp = new int[len];
dp[len - 1] = a[len - 1];
// 构建dp 数组,记录当前元素往后的最大值
for (int i = len - 2; i >= 0; i--)
dp[i] = Math.max(dp[i + 1], a[i]);
// 开始处理 push 时优先要弹出的元素
for (int i = 0; i < len; i++) {
// 如果栈顶元素比当前元素的往后的最大值大,说明截止上个元素的的最大值已经出现,满足弹出条件,弹出到比当前元素小即可
if (!stack.isEmpty() && stack.peek() > dp[i] )
while (!stack.isEmpty() && stack.peek() >= dp[i])
res[pos++] = stack.pop();
stack.push(a[i]);
}
// 剩余的元素直接弹出
while (!stack.isEmpty()) res[pos++] = stack.pop();
return res;
} import java.util.*;
public class Solution {
public int[] solve (int[] a) {
int[] rMax = new int[a.length]; // 当前位置之后的最大值(包括当前位置)
rMax[a.length - 1] = a[a.length - 1];
for (int i = a.length - 2; i >= 0 ; i--) {
rMax[i] = Math.max(rMax[i + 1], a[i]);
}
int index = 0;
int[] res = new int[a.length];
Deque<Integer> stack = new ArrayDeque<>();
for (int i = 0; i < a.length; i++) {
while (!stack.isEmpty() && stack.peek() > rMax[i]) { // 若栈顶比右侧大,则弹出
res[index++] = stack.pop();
}
stack.push(a[i]);
}
while (!stack.isEmpty()) {
res[index++] = stack.pop();
}
return res;
}
} class Solution {
public:
/**
* 栈排序
* @param a int整型一维数组 描述入栈顺序
* @param aLen int a数组长度
* @return int整型vector
*/
vector<int> solve(int* a, int aLen) {
// write code here
stack<int> s;
vector<int> res;
vector<bool> f(aLen + 1, false);
int now = aLen;
for(int i = 0; i < aLen; i ++){
s.push(a[i]);
f[a[i]] = true;
while(now > 0 && f[now])now --;
while(!s.empty() && s.top() > now){
res.push_back(s.top());
s.pop();
}
}
return res;
}
}; import java.util.*;
/**
* NC115 栈和排序
* @author d3y1
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 栈排序
* @param a int整型一维数组 描述入栈顺序
* @return int整型一维数组
*/
public int[] solve (int[] a) {
// return solution1(a);
// return solution2(a);
return solution3(a);
}
/**
* 模拟法: Stack+TreeSet
* @param a
* @return
*/
private int[] solution1(int[] a){
int n = a.length;
TreeSet<Integer> treeSet = new TreeSet<>((o1, o2) -> (o2-o1));
for(int i=n-1; i>=0; i--){
treeSet.add(a[i]);
if(a[i] == n){
break;
}
}
int max = treeSet.pollFirst();
int[] result = new int[n];
Stack<Integer> stack = new Stack<>();
int i = 0;
for(int num: a){
stack.push(num);
treeSet.remove(num);
if(stack.peek() == max){
result[i++] = stack.pop();
while(!stack.isEmpty() && !treeSet.isEmpty() && stack.peek()>treeSet.first()){
result[i++] = stack.pop();
}
if(!treeSet.isEmpty()){
max = treeSet.pollFirst();
}
}
}
while(!stack.isEmpty()){
result[i++] = stack.pop();
}
return result;
}
/**
* 模拟法: Stack(简化)
* @param a
* @return
*/
private int[] solution2(int[] a){
int n = a.length;
// rMax[i]: i右侧最大值(不包括自身)
int[] rMax = new int[n];
int max = a[n-1];
for(int i=n-2; i>=0; i--){
max = Math.max(max, a[i+1]);
rMax[i] = max;
}
int[] result = new int[n];
Stack<Integer> stack = new Stack<>();
for(int i=0,j=0; i<n; i++){
stack.push(a[i]);
if(stack.peek() == max){
result[j++] = stack.pop();
// rMax[n-1]=0 全部弹出
while(!stack.isEmpty() && stack.peek()>rMax[i]){
result[j++] = stack.pop();
}
max = rMax[i];
}
}
return result;
}
/**
* 模拟法: Stack(再简化)
* @param a
* @return
*/
private int[] solution3(int[] a){
int n = a.length;
// rMax[i]: i右侧最大值(包括自身)
int[] rMax = new int[n];
rMax[n-1] = a[n-1];
for(int i=n-2; i>=0; i--){
rMax[i] = Math.max(rMax[i+1], a[i]);
}
int[] result = new int[n];
Stack<Integer> stack = new Stack<>();
int j = 0;
for(int i=0; i<n; i++){
while(!stack.isEmpty() && stack.peek()>rMax[i]){
result[j++] = stack.pop();
}
stack.push(a[i]);
}
while(!stack.isEmpty()){
result[j++] = stack.pop();
}
return result;
}
} class Solution: def solve(self , a: List[int]) -> List[int]: stack = [] n = len(a) max_val = n res = [] for i in range(n): stack.append(a[i]) while stack and stack[-1] == max_val and i != n-1: res.append(stack.pop()) after_max = max(a[i+1:]) if stack and stack[-1] > after_max: max_val = stack[-1] else: max_val = after_max while stack: res.append(stack.pop()) return res
from operator import index # # 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 # # 栈排序 # @param a int整型一维数组 描述入栈顺序 # @return int整型一维数组 # class Solution: def solve(self , a: List[int]) -> List[int]: # write code here if len(a) == 0&nbs***bsp;len(a) == 1: return a stack = [] stack.append(a[0]) res = [] # 构建右视图最大表 right_max = [0 for i in range(len(a))] right_max[-1] = a[-1] for i in range(len(a)-2, -1, -1): right_max[i] = max(a[i], right_max[i + 1]) index = 1 while index < len(a): if len(stack) == 0: stack.append(a[index]) index += 1 continue # 栈顶大于入栈数,将栈顶加入结果 if stack[-1] >= right_max[index]: res.append(stack[-1]) stack.pop() else: stack.append(a[index]) index += 1 while len(stack) != 0: res.append(stack[-1]) stack.pop() return res
import java.util.*;
public class Solution {
/**
* 栈排序
* @param a int整型一维数组 描述入栈顺序
* @return int整型一维数组
*/
public int[] solve (int[] a) {
// write code here
//保存要返回的值
int arr[]=new int[a.length];
//创建集合保存结果
ArrayList<Integer> list = new ArrayList<>();
//创建栈
Stack<Integer> stack = new Stack<>();
stack.push(a[0]);
for (int i = 1; i < a.length; i++) {
int max = max(a, i);
//栈顶元素小于后面最大值,就入栈
if (stack.peek() < max) {
stack.push(a[i]);
} else {
//栈顶元素大于后面最大值,说明已经找到最大的,就出栈
//循环遍历,直到栈顶比后面最大值还小
while(!stack.isEmpty()&&stack.peek()>max){
list.add(stack.pop());
}
stack.push(a[i]);
}
}
//将值添加到数组并返回
while(!stack.isEmpty()){
list.add(stack.pop());
}
for(int i=0;i<list.size();i++){
arr[i]=list.get(i);
}
return arr;
}
public int max(int [] arr, int index) {
int max = Integer.MIN_VALUE;
for (int i = index; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
return max;
}
} import java.util.*;
public class Solution {
/**
* 栈排序
* @param a int整型一维数组 描述入栈顺序
* @return int整型一维数组
*/
public int[] solve (int[] a) {
// write code here
int n = a.length;
Deque<Integer> stack = new ArrayDeque<>();
int[] maxArr = new int[n];
// 倒叙记录每个位置元素后面出现的最大元素
maxArr[n-1] = Integer.MIN_VALUE;
int tempMax = Integer.MIN_VALUE;
for(int i=a.length-2;i>=0;i--){
maxArr[i] = Math.max(a[i+1], maxArr[i+1]);
}
for(int i=0;i<n;i++){
System.out.print(maxArr[i]+" ");
}
int[] ans = new int[n];
int index = 0;
for(int i=0;i<n;i++){
if(a[i] > maxArr[i]){ // 当前入栈元素大于将要入栈的元素
ans[index++] = a[i];
while(!stack.isEmpty() && stack.peek()>maxArr[i]){
ans[index++] = stack.pop();
}
}else{
stack.push(a[i]);
}
}
while(!stack.isEmpty()){
ans[index++] = stack.pop();
}
return ans;
}
} # # 栈排序 # @param a int整型一维数组 描述入栈顺序 # @return int整型一维数组 # class Solution: def solve(self , a ): # write code here n, stack, dp, res = len(a), [], [0]*len(a), [] dp[-1] = a[-1] # 记录从第i个元素开始到最后的最大元素 for i in range(n-2, -1, -1): dp[i] = max(dp[i+1], a[i]) for i in range(n): stack.append(a[i]) while stack and i < n-1 and stack[-1]>=dp[i+1]: res.append(stack.pop()) # 如果栈顶元素比后面所有元素都大,则弹出 while stack: res.append(stack.pop()) return res
class Solution {
public:
/**
* 栈排序
* @param a int整型一维数组 描述入栈顺序
* @param aLen int a数组长度
* @return int整型vector
*/
vector<int> solve(int* a, int aLen) {
// write code here
vector<int> res;
stack<int> aux;
int i=0;
aux.push(a[i++]);
while (aux.size()||i<=aLen){
if(i==aLen){
while(aux.size()){
res.push_back(aux.top());
aux.pop();
}
i++;
}
else{
if(aux.size()){
int top=aux.top();
int next_max=*(std::max_element(a+i,a+aLen));
while(top>next_max){
aux.pop();
res.push_back(top);
if(aux.size())
top=aux.top();
else
break;
}
}
aux.push(a[i++]);
}
}
return res;
}
};