算法题每日一练---第94天:棒球比赛

1,245 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第29天,点击查看活动详情

一、问题描述

你现在是一场采用特殊赛制棒球比赛的记录员。这场比赛由若干回合组成,过去几回合的得分可能会影响以后几回合的得分。

比赛开始时,记录是空白的。你会得到一个记录操作的字符串列表 ops,其中 ops[i] 是你需要记录的第 i 项操作,ops 遵循下述规则:

    1.  整数 `x` - 表示本回合新获得分数 `x`
    
    2.  `"+"` - 表示本回合新获得的得分是前两次得分的总和。
    题目数据保证记录此操作时前面总是存在两个有效的分数。
    
    3.  `"D"` - 表示本回合新获得的得分是前一次得分的两倍。
    题目数据保证记录此操作时前面总是存在一个有效的分数。
    
    4.  `"C"` - 表示前一次得分无效,将其从记录中移除。
    题目数据保证记录此操作时前面总是存在一个有效的分数。

请你返回记录中所有得分的总和

题目链接:棒球比赛

二、题目要求

样例

输入: 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

考察

1.模拟
2.建议用时15~25min

三、问题分析

这也是一道比较典型的模拟题,主要考察了四个状态。我们通过vectorv数组存储生成的记录,当然用栈也是可以的。

首先,我们先遍历数组分为四个状态:

  • + :新元素的值等于前两个元素值之和
  • D:新元素的值等于前一个元素的2倍
  • C:删除末尾的元素
  • 数字:转换成数字存入数组

注意:

通常来说,char型的变量转为int,只需要-'0'就行了,但是这题说了数组里面的每一个元素都是字符串。

所以我们要用到字符串转数字的函数stoi(字符串,起始位置,n进制),这里我们默认10进制,整个字符串,所以直接调用就行。

四、编码实现

class Solution {
public:
    int calPoints(vector<string>& ops) {
        int i,k,sum=0,n=ops.size();//初始化数据
        vector<int>v;//数组存储记录
        for(i=0;i<n;i++)
        {
            k=v.size();//当前的数组大小
            if(ops[i]=="+")//新元素的值等于前两个元素值之和
            {
                v.push_back(v[k-1]+v[k-2]);
            }
            else if(ops[i]=="D")//新元素的值等于前一个元素的2倍
            {
                v.push_back(2*v[k-1]);
            }
            else if(ops[i]=="C")//删除末尾的元素
            {
                v.pop_back();
            }
            else//转换成数字存入数组
            {
                v.push_back(stoi(ops[i]));
            }
        }
        for(i=0;i<v.size();i++)//求和
            sum+=v[i];
        return sum;

    }
};

五、测试结果

2.png

1.png