现在图书馆有一堆图书需要放入书架,并且图书馆的书架是一种特殊的数据结构,只能按照 一定 的顺序 放入 和 拿取 书籍。
给定一个表示图书放入顺序的整数序列 putIn,请判断序列 takeOut 是否为按照正确的顺序拿取书籍的操作序列。你可以假设放入书架的所有书籍编号都不相同。
示例 1:
输入:putIn = [6,7,8,9,10,11], takeOut = [9,11,10,8,7,6]
输出:true
解释:我们可以按以下操作放入并拿取书籍:
push(6), push(7), push(8), push(9), pop() -> 9,
push(10), push(11),pop() -> 11,pop() -> 10, pop() -> 8, pop() -> 7, pop() -> 6
示例 2:
输入:putIn = [6,7,8,9,10,11], takeOut = [11,9,8,10,6,7]
输出:false
解释:6 不能在 7 之前取出。
提示:
0 <= putIn.length == takeOut.length <= 1000
0 <= putIn[i], takeOut < 1000
putIn 是 takeOut 的排列。
对于示例1,可以总结出如下的思路:首先要两个指针i, j和一个栈s。先遍历putIn,如果putIn[i]的元素和takeOut[j]不相等就放入s中,如果相等就不进栈,只把j++。
最后把s所有元素依次弹出和takeOut[j]一个一个对比,如果不相等就返回false。
但是碰到[2, 1, 0] [1, 2, 0]这个用例之后会出错。
要在这里及时把栈顶和takeOut[j]相同的元素弹出
for(int i = 0;i < len && j < len;i++){
if(putIn[i] != takeOut[j]){
s.push(putIn[i]);
} else {
j++;
//2, 1, 0 1, 2, 0
while(!s.empty() && j < len && s.top() == takeOut[j]){
s.pop();
j++;
}
}
}
原因是忽略了在这种地方:
push(6), push(7), push(8), push(9), pop() -> 9, push(10), push(11),pop() -> 11,pop() -> 10, pop() -> 8, pop() -> 7, pop() -> 6
这种地方可能要弹栈多次的可能。
class Solution {
public:
bool validateBookSequences(vector<int>& putIn, vector<int>& takeOut) {
bool res = true;
int len = putIn.size(), j = 0;
stack<int> s;
for(int i = 0;i < len && j < len;i++){
if(putIn[i] != takeOut[j]){
s.push(putIn[i]);
} else {
j++;
//2, 1, 0 1, 2, 0
while(!s.empty() && j < len && s.top() == takeOut[j]){
s.pop();
j++;
}
}
}
while(!s.empty() && j < len){
if(s.top() == takeOut[j]){
s.pop();
j++;
} else {
res = false;
break;
}
}
return res;
}
};