一、题目
Given a stack which can keep M numbers at most. Push N numbers in the order of 1, 2, 3, ..., N and pop randomly. You are supposed to tell if a given sequence of numbers is a possible pop sequence of the stack. For example, if M is 5 and N is 7, we can obtain 1, 2, 3, 4, 5, 6, 7 from the stack, but not 3, 2, 1, 7, 5, 6, 4.
Input Specification:
Each input file contains one test case. For each case, the first line contains 3 numbers (all no more than 1000): M (the maximum capacity of the stack), N (the length of push sequence), and K (the number of pop sequences to be checked). Then K lines follow, each contains a pop sequence of N numbers. All the numbers in a line are separated by a space.
Output Specification:
For each pop sequence, print in one line "YES" if it is indeed a possible pop sequence of the stack, or "NO" if not.
Sample Input:
5 7 5
1 2 3 4 5 6 7
3 2 1 7 5 6 4
7 6 5 4 3 2 1
5 6 4 3 7 2 1
1 7 6 5 4 3 2
Sample Output:
YES
NO
NO
YES
NO
二、解答
import java.util.*;
public class Main {
static ArrayList<Integer> stack = new ArrayList<>();
static int index = -1;
static int stackCap = -1;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
stackCap = sc.nextInt();
int length = sc.nextInt();
int caseNum = sc.nextInt();
//不想一边输入一边输出,所以还是先读取输入,最后再一次性输出
//Get Case
int[][] arrs = new int[caseNum][length];
for (int i = 0; i < caseNum; i++) {
for (int j = 0; j < length; j++) {
arrs[i][j] = sc.nextInt();
}
}
//Judge
for (int i = 0; i < caseNum ; i++) {
judge(arrs[i]);
}
}
public static void judge (int[] arr){
clearStack();
//java初始化数组默认全为0
int[] visited = new int[arr.length + 1];
boolean res = true;
for (int i = 0; i < arr.length ; i++) {
if (stack.contains(arr[i])){
if (stack.indexOf(arr[i]) != index || !pop()) {res = false; break;}
} else {
int temp = 1;
while((!stack.contains(arr[i])) && temp <= arr.length){
//入堆栈
if (visited[temp] == 1) temp++;
else if (push(temp)) {visited[temp++] = 1;}
else{res = false; break;}
}
pop();
}
}
System.out.println(res ? "YES" : "NO");
}
public static void clearStack(){
stack.clear();
index = -1;
}
public static boolean push(int num){
//堆栈满了报错
if (index + 1 >= stackCap) return false;
stack.add(num);
index++;
return true;
}
public static boolean pop(){
//堆栈为空报错
if (index < 0) return false;
stack.remove(index--);
return true;
}
}
思路:
- 试着找规律发现没有什么规律
- 从模拟堆栈运行过程去考虑:想要弹出N,必须把0~N-1的数都曾经压入过堆栈
- 考虑如何将数据进行存放:存放到一个二维数组中即可
- 考虑如何进行判断:获取当前需要弹出的值,判断其是否已经在堆栈中:如果在堆栈中,则该数必须在堆栈最上面,否则为错;如果不在堆栈中,则需要将小于这个数的所有值都压入堆栈(如果曾经压入过已经弹出堆栈的,需要做标记,如何跳过,不再重复压入)
- 完善压入弹出操作:堆栈容量有限,设置溢出报警和空堆栈报警
- 一定注意:index和stack为全局变量,判断完一组数必须清空堆栈才能进行下一次判断
思考:
可能是因为java原因,运行最大N时超时