题目
(1)你现在是一场采用特殊赛制棒球比赛的记录员。这场比赛由若干回合组成,过去几回合的得分可能会影响以后几回合的得分。
(2)比赛开始时,记录是空白的。你会得到一个记录操作的字符串列表 ops,其中 ops[i] 是你需要记录的第 i 项操作,ops 遵循下述规则:
- 整数 x:表示本回合新获得分数 x
- “+” :表示本回合新获得的得分是前两次得分的总和。题目数据保证记录此操作时前面总是存在两个有效的分数。
- “D”:表示本回合新获得的得分是前一次得分的两倍。题目数据保证记录此操作时前面总是存在一个有效的分数。
- “C”:表示前一次得分无效,将其从记录中移除。题目数据保证记录此操作时前面总是存在一个有效的分数。
(3)请你返回记录中所有得分的总和。
(4)示例如下:
输入: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
解决思路
- 用栈记录分数,当前分数有效,就将分数入栈;删除前一次得分对应着弹栈。
代码
- C++完整代码
# include <stdio.h>
# include <stack>
# include <vector>
# include <string>
using namespace std;
class Solution {
public:
int calPoints(vector<string>& ops) {
stack<int> score; // 用栈记录得分
int sum = 0; // 总得分
for (int i = 0; i < ops.size(); i++) {
if ("+" == ops[i]) {
int a = score.top();
score.pop();
int b = score.top();
score.push(a);
score.push(a + b);
} else if ("D" == ops[i]) {
score.push(2 * score.top());
} else if ("C" == ops[i]) {
score.pop();
} else {
// 将字符串转为整型,然后加入到栈中
score.push(atoi(ops[i].c_str()));
}
}
while (!score.empty()) {
sum += score.top();
score.pop();
}
return sum;
}
};
int main() {
vector<string> ops = {"5","2","C","D","+"};
Solution *solution = new Solution();
int ret = solution->calPoints(ops);
printf("%d\n", ret);
return 0;
}
- Python代码
# -*- coding: utf-8 -*-
from typing import List
class Solution:
def __init__(self):
pass
def calPoints(self, ops: List[str]) -> int:
score = [] # 用list模拟栈,记录得分
for i in ops:
if "+" == i:
score.append(score[-1] + score[-2])
elif "D" == i:
score.append(2 * score[-1])
elif "C" == i:
score.pop()
else:
# 将字符串转为整型,然后加入到list中
score.append(int(i))
return sum(score)
def main():
ops = ["5", "2", "C", "D", "+"]
solution = Solution()
print(solution.calPoints(ops))
if __name__ == "__main__":
main()
说明
- 对应LeetCode第682题。
- 链接:https://leetcode-cn.com/problems/baseball-game/