「这是我参与2022首次更文挑战的第4天,活动详情查看:2022首次更文挑战」
前言
今天我们来研究一项特殊赛制棒球比赛的积分规则,当回小福尔摩斯破译一下某个队伍在这场比赛中究竟拿了多少分,我们的先遣队拿到了加密过的球队成绩,并且我们从leetcode官方套出了得分的关键消息,下面请看规则。
规则描述
682. 棒球比赛
比赛开始时,记录是空白的。你会得到一个记录操作的字符串列表 ops,其中 ops[i] 是你需要记录的第 i 项操作,ops 遵循下述规则:
整数 x
- 表示本回合新获得分数 x
"+" - 表示本回合新获得的得分是前两次得分的总和。题目数据保证记录此操作时前面总是存在两个有效的分数。
"D" - 表示本回合新获得的得分是前一次得分的两倍。题目数据保证记录此操作时前面总是存在一个有效的分数。
"C" - 表示前一次得分无效,将其从记录中移除。题目数据保证记录此操作时前面总是存在一个有效的分数。 请你返回记录中所有得分的总和。
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/ba… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
规则解析
从计分规则来看,我们需要将球队成绩中的符号与积分规则对比,并且我们需要通过栈来存储我们的得分,作为最后我们算总分的依据。那么,我们该根据怎么样的规则计算分数然后放到栈里呢?
- 球队成绩数组中放的都是字符串,那么我们需不需要判断
整数x这个情况呢,可能你还会想到用强制字符串看是不是一个数字对吧,但其实我们只需要判断是否是"+"、"D"、"C"其中的一个,如果不是那么就是整数对吧? - 到这里你可能说,for 循环加 if..else if 这我熟悉,拜托,我们用点不一样的方法好吗,还能简化下代码,比如:
while循环+switch case这不香吗,后面解题会体现出来。 - 那么我们辅助工具有了,分析下操作方法吧:
- 如果不是'+','D','C'中的一个,那么就是整数,我们直接将其转化为数字执行入栈操作
- 如果是'+',将栈顶第一位和第二位得分相加作为我们新的分数执行入栈操作
- 如果是'D',将栈顶得分乘以2作为我们新的分数执行入栈
- 如果是'C',说明栈顶得分是无效的,这次我们只需要将栈顶元素出栈就行,无新得分入栈
- 最后一步,直接用reduce函数求栈中所有分数之和就是我们要破译的球队的比赛得分了
开始破译
var calPoints = function(ops) {
let recordArr = []; // 初始化一个空的数组用来 记录分数
while(ops.length) { // 遍历成绩字符串数组,长度为0即停止破译
let len = recordArr.length;
switch(ops[0]) { // 每次破译第一项即可
case '+' :
recordArr.push(recordArr[len-1] + recordArr[len-2]); // 本次得分为栈顶前两个分数之和
break;
case 'D' :
recordArr.push(recordArr[len-1]*2); // 本次得分为上次2倍
break;
case 'C' :
recordArr.pop(); // 上次得分无效,栈顶元素出栈
break;
default:
recordArr.push(Number(ops[0])); // 将整数字符串转为数字入栈
}
ops.shift(); // 破译完一次得分就删除该得分记录
}
return recordArr.reduce((a,b) => a + b);
};