偶然遇到了这道题,乍一看题目完全没懂什么意思,稍微琢磨后大致明白了原理和考察的结构。
题目:
有一个死胡同,宽度刚好只能让一辆汽车通过,偏偏老有汽车开到死胡同来,这下麻烦了,最先开来的汽车要最后才能倒退出去。给定一个汽车开来的序列和一个可能的倒车出去的序列,请判断汽车能否都倒退出去,若能则输出Yes,否则输出No。
输入格式:
首先输入一个整数T,表示测试数据的组数,然后是T组测试数据。每组测试数据首先输入一个正整数n(n≤10),代表开来的汽车数,然后输入2n个整数,其中,前n个整数表示汽车开来的序列,后n个整数表示汽车可能倒出的序列。
输入样例
2
4 1 2 3 4 2 1 4 3
4 1 2 3 4 4 2 1 3
题目中既然是倒车问题,倒车是先进后出,很明显是栈的结构。
每一行数据的开头为车辆的数量,我们不妨将车辆看作一个个函数,
进入序列:1 2 3 4 看作栈,倒车序列:2 1 4 3 ,2先执行,则函数2在栈顶,然后是函数1,执行成功了即函数全部出栈,否则执行失败,有了这样的思路后就能比较轻松的写出代码了。
main函数及变量
这里没什么好说的,就简单的输入数据。
static Scanner input=new Scanner(System.in);
static ArrayList<Integer> stack;//栈序列
static ArrayList<Integer> run;//运行序列
public static void main(String[] args) {//主函数输入
int T=input.nextInt();
for(int i=0;i<T;i++){//每组数据输入
int nums=input.nextInt();//每组数据的汽车数量
stack=new ArrayList<>();//重置
run=new ArrayList<>();
for(int j=0;j<nums;j++){//栈序列添加元素
stack.add(input.nextInt());
}
for(int j=0;j<nums;j++){//运行序列添加元素
run.add(input.nextInt());
}
System.out.println(isRight(stack,run,nums)?"Yes":"No");//判断并输出
}
}
isRight函数
这里运用了双指针法,一个index指向stack,一个point指向run,
当point和index两者指向的元素值相等时,则代表着函数执行成功,该函数即为栈顶,即最后一个执行的函数,否则继续在栈中寻找函数。
需要注意的是index--:因为每一个函数出栈后,这个函数必定是栈顶的函数,下一个出栈的函数只能是该函数的下一位,所以index--
private static boolean isRight(ArrayList<Integer> stack,ArrayList<Integer> run,int nums){
int index=0;//指向stack
int point=0;//指向run
boolean isRight=true;
while (stack.size()>0){
if(index>=stack.size())//当栈指针超过栈的大小
{
isRight=false;
break;
}
int stackItem=stack.get(index);
int runItem=run.get(point);
if(stackItem==runItem){//相等
stack.remove(stack.get(index));
if (index>0){//每次出栈后,下一个出栈的函数从已出栈函数的下方去找
index--;
}
point++;//运行指针右移一位
}
else {
index++;//指针移动
}
}
return isRight;
}
所以
4 1 2 3 4 2 1 4 3
代表着 1进,2进,2出,1出,3进,4进,4出,3出。
所以上文的输入样例执行结果为
Yes
No
Process finished with exit code 0
这是本人在学习时一点小小的总结,希望对你学习能有所帮助。