题目
946. 验证栈序列
给定 pushed 和 popped 两个序列,每个序列中的 值都不重复,只有当它们可能是在最初空栈上进行的推入 push 和弹出 pop 操作序列的结果时,返回 true;否则,返回 false 。
思路:
最容易理解,不带任何优化
可以用栈的思想去做,
- 申明一个栈stack,一个计数器count,一个结果数组arr,遍历字符串,遇到"(",如果当前stack为空,则计数器count++,并把当前项拼接在arr[count]项上,如果stack不为空,则直接拼接。然后将"("入栈,
- 遇到")"则出栈并把当前项拼接在arr[count]项上
- 遍历得到的arr结果数组,将每一项的头尾去掉,并把所有项都拼接起来
代码如下:
/**
* @param {string} s
* @return {string}
*/
var removeOuterParentheses = function(s) {
let stack = [];
let arr = [];
let count = -1;
let result = '';
for(let i=0;i<s.length;i++){
if(s[i] == '('){
if(stack.length == 0){
count++;
arr[count] = '';
}
stack.push('(');
arr[count] += s[i]
}else if(s[i] == ')'){
stack.pop();
arr[count] += s[i]
}
}
for(let i=0;i<arr.length;i++){
result += arr[i].slice(1,arr[i].length-1)
}
return result
};
优化:
我们其实可以不用最后再去处理结果,而是遍历字符串的过程中就将结果拼接好,只需要遍历过程中判断如果stack为空的时候,则不拼接当前项即可
代码如下:
/**
* @param {string} s
* @return {string}
*/
var removeOuterParentheses = function(s) {
let stack = [];
let result = '';
for(let i=0;i<s.length;i++){
if(s[i] == '('){
if(stack.length != 0){
result += s[i]
}
stack.push('(');
}else if(s[i] == ')'){
stack.pop();
if(stack.length != 0){
result += s[i]
}
}
}
return result
};
继续优化:
我们虽然用栈的思想,但写法可以改变,不用真的用stack去记录,可以用计数器来模拟栈,代码优化如下
/**
* @param {string} s
* @return {string}
*/
var removeOuterParentheses = function(s) {
let count = 0;
let result = '';
for(let i=0;i<s.length;i++){
if(s[i] == '('){
if(count > 0){
result += s[i]
}
count++;
}else if(s[i] == ')'){
count--;
if(count > 0){
result += s[i]
}
}
}
return result
};
思路2:
这题出了可以用栈,还可以用双指针解法,
- 定义一个left指针记录一个原语的其实下标,定义一个计数器count,
- 遍历字符串,同样式遇到"("则count++,遇到")"则count--,
- 当count为0时,当前项就是一个原语的右括号,记录下标,并取出这个原语的内容拼接在结果上,往后依次类推
代码如下:
/**
* @param {string} s
* @return {string}
*/
var removeOuterParentheses = function(s) {
let count = 0;
let result = '';
let left = 0;
let temp = 0;
for(let i=0;i<s.length;i++){
if(s[i] == '('){
count++
}else if(s[i] == ')'){
count--
if(count == 0){
result += s.slice(left+1,i)
left = i+1;
}
}
}
return result;
};