棒球比赛
问题描述: 你现在是一场采用特殊赛制棒球比赛的记录员。这场比赛由若干回合组成,过去几回合的得分可能会影响以后几回合的得分。(by leetcode 682)
比赛开始时,记录是空白的。你会得到一个记录操作的字符串列表 ops,其中 ops[i] 是你需要记录的第 i 项操作,ops 遵循下述规则:
- 整数
x- 表示本回合新获得分数x "+"- 表示本回合新获得的得分是前两次得分的总和。题目数据保证记录此操作时前面总是存在两个有效的分数。"D"- 表示本回合新获得的得分是前一次得分的两倍。题目数据保证记录此操作时前面总是存在一个有效的分数。"C"- 表示前一次得分无效,将其从记录中移除。题目数据保证记录此操作时前面总是存在一个有效的分数。
请你返回记录中所有得分的总和。
示例 1:
输入:ops = ["5","2","C","D","+"]
输出:30
解释:
"5" - 记录加 5 ,记录现在是 [5]
"2" - 记录加 2 ,记录现在是 [5, 2]
"C" - 使前一次得分的记录无效并将其移除,记录现在是 [5].
"D" - 记录加 2 * 5 = 10 ,记录现在是 [5, 10].
"+" - 记录加 5 + 10 = 15 ,记录现在是 [5, 10, 15].
所有得分的总和 5 + 10 + 15 = 30
思路:
/**
* @param {string[]} ops
* @return {number}
*/
var calPoints = function(ops) {
let endArr=[];
for(let i=0;i<ops.length;i++){
switch(ops[i]){
case 'C':
// endArr.splice(0,endArr.length-1);
endArr.pop()
break;
case 'D':
endArr[endArr.length]=2*endArr[endArr.length-1];
break;
case '+':
endArr[endArr.length]=endArr[endArr.length-2]+endArr[endArr.length-1];
break;
default:
endArr[endArr.length]=Number(ops[i]);
break;
}
}
let num=endArr.reduce(function(total,cur){return total+cur});
return num
};
比较含退格的字符串
问题描述: 给定 s 和 t 两个字符串,当它们分别被输入到空白的文本编辑器后,请你判断二者是否相等。# 代表退格字符。
如果相等,返回 true ;否则,返回 false 。(by leetcode 844)
注意: 如果对空文本输入退格字符,文本继续为空。
示例 1:
输入:s = "ab#c", t = "ad#c"
输出:true
解释:S 和 T 都会变成 “ac”。
示例 2:
输入:s = "ab##", t = "c#d#"
输出:true
解释:s 和 t 都会变成 “”。
思路:
/**
* @param {string} s
* @param {string} t
* @return {boolean}
*/
function formatStr(s,endS){
for(let i=0;i<s.length;i++){
if(s[i]!=='#'){
endS.push(s[i])
}else{
endS.pop()
}
}
}
var backspaceCompare = function(s, t) {
s=s.split("");
t=t.split("");
while(s[0]=='#'){
s.shift();
}while(t[0]=='#'){
t.shift();
}
let endS=[],endT=[];
formatStr(s,endS)
formatStr(t,endT)
s=endS.join("")
t=endT.join("")
return s==t
};
删除最外层的括号
问题描述: 有效括号字符串为空 ""、"(" + A + ")" 或 A + B ,其中 A 和 B 都是有效的括号字符串,+ 代表字符串的连接。
- 例如,
"","()","(())()"和"(()(()))"都是有效的括号字符串。
如果有效字符串 s 非空,且不存在将其拆分为 s = A + B 的方法,我们称其为原语(primitive),其中 A 和 B 都是非空有效括号字符串。
给出一个非空有效字符串 s,考虑将其进行原语化分解,使得:s = P_1 + P_2 + ... + P_k,其中 P_i 是有效括号字符串原语。
对 s 进行原语化分解,删除分解中每个原语字符串的最外层括号,返回 s 。(by leetcode 1021)
示例 1:
输入:s = "(()())(())"
输出:"()()()"
解释:
输入字符串为 "(()())(())",原语化分解得到 "(()())" + "(())",
删除每个部分中的最外层括号后得到 "()()" + "()" = "()()()"。
思路:拿到题目先不要着急下手,观察,可以通过一个变量来记录是否遇到合并括号。
/**
* @param {string} s
* @return {string}
*/
var removeOuterParentheses = function(s) {
s=s.split("")
let level=0;
let sb="";
for(let i=0;i<s.length;i++){
if(s[i]==")")level--;
if(level>=1)sb+=s[i];
if(s[i]=="(")level++
}
return sb;
};
化栈为队
问题描述: 实现一个MyQueue类,该类用两个栈来实现一个队列。(by leetcode 03.04)
示例:
MyQueue queue = new MyQueue();
queue.push(1);
queue.push(2);
queue.peek(); // 返回 1
queue.pop(); // 返回 1
queue.empty(); // 返回 false
思路: 设置一个入栈,设置一个出栈。(想象自己有两个网球桶,左手一个,右手一个,要取到左手桶里最下面的,就得先倒到右手桶里,再去拿。)
var MyQueue = function() {
this.stackIn=[];
this.stackOut=[];
};
/**
* Push element x to the back of queue.
* @param {number} x
* @return {void}
*/
MyQueue.prototype.push = function(x) {
this.stackIn.push(x);
};
/**
* Removes the element from in front of queue and returns that element.
* @return {number}
*/
MyQueue.prototype.pop = function() {
while(this.stackIn.length>1){
this.stackOut.push(this.stackIn.pop())
}
let ans=this.stackIn.pop();
while(this.stackOut.length){
this.stackIn.push(this.stackOut.pop())
}
return ans;
};
/**
* 获取栈顶元素
* Get the front element.
* @return {number}
*/
MyQueue.prototype.peek = function() {
while(this.stackIn.length>1){
this.stackOut.push(this.stackIn.pop())
}
let ans=this.stackIn[0];
while(this.stackOut.length){
this.stackIn.push(this.stackOut.pop())
}
return ans;
};
/**
* Returns whether the queue is empty.
* @return {boolean}
*/
MyQueue.prototype.empty = function() {
return !this.stackIn.length&&!this.stackOut.length
};
验证栈序列
问题描述: 给定 pushed 和 popped 两个序列,每个序列中的 值都不重复,只有当它们可能是在最初空栈上进行的推入 push 和弹出 pop 操作序列的结果时,返回 true;否则,返回 false 。(by leetcode 946)
示例 1:
输入:pushed = [1,2,3,4,5], popped = [4,5,3,2,1]
输出:true
解释:我们可以按以下顺序执行:
push(1), push(2), push(3), push(4), pop() -> 4,
push(5), pop() -> 5, pop() -> 3, pop() -> 2, pop() -> 1
思路: 在pushed上设置一个指针i,当pushed[i]跟poped第一个值相等,那个删除pushed上这个值跟poped的第一个值。若不相等,指针向前一位进行比较,相同则删除这个值跟poped的第一个值,指针向前。直到最后看剩余两个数组是不是互为对方的倒序,是的话则是正确的栈序列,且中间两数组长度不一致则一定不是。
/**
* @param {number[]} pushed
* @param {number[]} popped
* @return {boolean}
*/
var validateStackSequences = function(pushed, popped) {
if(pushed.length != popped.length){
return false;
}
let i=0;
while(pushed[i]||pushed[i]==0){
if(pushed[i]!=popped[0]){
if(i>0&&pushed[i-1]==popped[0]){
pushed.splice(i-1,1)
popped.shift();
i--;
}else{
i++;
}
}else{
pushed.splice(i,1)
popped.shift();
}
}
if(pushed.length != popped.length){
return false;
}
for(let i=0;i<popped.length;i++){
if(pushed[i]!==popped[pushed.length-1-i]){
return false
}
}
return true
};