你现在是一场采用特殊赛制棒球比赛的记录员。这场比赛由若干回合组成,过去几回合的得分可能会影响以后几回合的得分。
比赛开始时,记录是空白的。你会得到一个记录操作的字符串列表 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
示例 2:
**输入:** ops = ["5","-2","4","C","D","9","+","+"]
**输出:** 27
**解释:**
"5" - 记录加 5 ,记录现在是 [5]
"-2" - 记录加 -2 ,记录现在是 [5, -2]
"4" - 记录加 4 ,记录现在是 [5, -2, 4]
"C" - 使前一次得分的记录无效并将其移除,记录现在是 [5, -2]
"D" - 记录加 2 * -2 = -4 ,记录现在是 [5, -2, -4]
"9" - 记录加 9 ,记录现在是 [5, -2, -4, 9]
"+" - 记录加 -4 + 9 = 5 ,记录现在是 [5, -2, -4, 9, 5]
"+" - 记录加 9 + 5 = 14 ,记录现在是 [5, -2, -4, 9, 5, 14]
所有得分的总和 5 + -2 + -4 + 9 + 5 + 14 = 27
示例 3:
**输入:** ops = ["1"]
**输出:** 1
提示:
1 <= ops.length <= 1000
ops[i]
为 "C"
、"D"
、"+"
,或者一个表示整数的字符串。整数范围是 [-3 * 104, 3 * 104]
对于 "+"
操作,题目数据保证记录此操作时前面总是存在两个有效的分数
对于 "C"
和 "D"
操作,题目数据保证记录此操作时前面总是存在一个有效的分数
方法一:模拟 思路与算法
使用变长数组对栈进行模拟。
如果操作是 +,那么访问数组的后两个得分,将两个得分之和加到总得分,并且将两个得分之和入栈。
如果操作是 D,那么访问数组的最后一个得分,将得分乘以 2 加到总得分,并且将得分乘以 2 入栈。
如果操作是 C,那么访问数组的最后一个得分,将总得分减去该得分,并且将该得分出栈。
如果操作是整数,那么将该整数加到总得分,并且将该整数入栈。
代码
[sol1-Python3] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Solution : def calPoints (self, ops: List [str ] ) -> int : ans = 0 points = [] for op in ops: if op == '+' : pt = points[-1 ] + points[-2 ] elif op == 'D' : pt = points[-1 ] * 2 elif op == 'C' : ans -= points.pop() continue else : pt = int (op) ans += pt points.append(pt) return ans
[sol1-C++] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 class Solution {public : int calPoints (vector<string>& ops) { int ret = 0 ; vector<int > points; for (auto &op : ops) { int n = points.size (); switch (op[0 ]) { case '+' : ret += points[n - 1 ] + points[n - 2 ]; points.push_back (points[n - 1 ] + points[n - 2 ]); break ; case 'D' : ret += 2 * points[n - 1 ]; points.push_back (2 * points[n - 1 ]); break ; case 'C' : ret -= points[n - 1 ]; points.pop_back (); break ; default : ret += stoi (op); points.push_back (stoi (op)); break ; } } return ret; } };
[sol1-Java] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 class Solution { public int calPoints (String[] ops) { int ret = 0 ; List<Integer> points = new ArrayList <Integer>(); for (String op : ops) { int n = points.size(); switch (op.charAt(0 )) { case '+' : ret += points.get(n - 1 ) + points.get(n - 2 ); points.add(points.get(n - 1 ) + points.get(n - 2 )); break ; case 'D' : ret += 2 * points.get(n - 1 ); points.add(2 * points.get(n - 1 )); break ; case 'C' : ret -= points.get(n - 1 ); points.remove(n - 1 ); break ; default : ret += Integer.parseInt(op); points.add(Integer.parseInt(op)); break ; } } return ret; } }
[sol1-C#] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 public class Solution { public int CalPoints (string [] ops ) { int ret = 0 ; IList<int > points = new List<int >(); foreach (string op in ops) { int n = points.Count; switch (op[0 ]) { case '+' : ret += points[n - 1 ] + points[n - 2 ]; points.Add(points[n - 1 ] + points[n - 2 ]); break ; case 'D' : ret += 2 * points[n - 1 ]; points.Add(2 * points[n - 1 ]); break ; case 'C' : ret -= points[n - 1 ]; points.RemoveAt(n - 1 ); break ; default : ret += int .Parse(op); points.Add(int .Parse(op)); break ; } } return ret; } }
[sol1-C] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 int calPoints (char ** ops, int opsSize) { int ret = 0 ; int * points = (int *)malloc (sizeof (int ) * opsSize); int pos = 0 ; for (int i = 0 ; i < opsSize; i++) { switch (ops[i][0 ]) { case '+' : ret += points[pos - 1 ] + points[pos - 2 ]; points[pos++] = points[pos - 1 ] + points[pos - 2 ]; break ; case 'D' : ret += 2 * points[pos - 1 ]; points[pos++] = 2 * points[pos - 1 ]; break ; case 'C' : ret -= points[pos - 1 ]; pos--; break ; default : ret += atoi(ops[i]); points[pos++] = atoi(ops[i]); break ; } } free (points); return ret; }
[sol1-JavaScript] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 var calPoints = function (ops ) { let ret = 0 ; const points = []; for (const op of ops) { const n = points.length ; switch (op[0 ]) { case '+' : ret += points[n - 1 ] + points[n - 2 ]; points.push (points[n - 1 ] + points[n - 2 ]); break ; case 'D' : ret += 2 * points[n - 1 ]; points.push (2 * points[n - 1 ]); break ; case 'C' : ret -= points[n - 1 ]; points.pop (); break ; default : ret += parseInt (op); points.push (parseInt (op)); break ; } } return ret; };
[sol1-Golang] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 func calPoints (ops []string ) (ans int ) { points := []int {} for _, op := range ops { n := len (points) switch op[0 ] { case '+' : ans += points[n-1 ] + points[n-2 ] points = append (points, points[n-1 ]+points[n-2 ]) case 'D' : ans += points[n-1 ] * 2 points = append (points, 2 *points[n-1 ]) case 'C' : ans -= points[n-1 ] points = points[:len (points)-1 ] default : pt, _ := strconv.Atoi(op) ans += pt points = append (points, pt) } } return }
复杂度分析