小E的比赛得分计算

128 阅读3分钟

问题描述

小E正在参加一系列比赛,共有nn场比赛。赢得一场比赛可以获得1分,而如果连续赢得两场或更多比赛,第二场及之后的每一场比赛都会额外获得1分。现在,给定nn场比赛的结果,请计算小E的总分数。


测试样例

样例1:

输入:n = 5, a = [1, 1, 1, 0, 1]
输出:6

样例2:

输入:n = 3, a = [1, 0, 1]
输出:2

样例3:

输入:n = 6, a = [1, 1, 0, 0, 1, 1]
输出:6

样例4:

输入:n = 4, a = [0, 0, 1, 1]
输出:3

问题理解

小E参加了一系列比赛,每场比赛的结果用一个数组 a 表示,其中 1 表示赢,0 表示输。赢得一场比赛可以获得1分,但如果连续赢得多场比赛,从第二场开始每场都会额外获得1分。

数据结构选择

我们可以直接使用数组 a 来存储比赛结果。

算法步骤

  1. 初始化总分数:用一个变量 sum 来记录总分数,初始值为0。

  2. 遍历比赛结果数组:使用一个循环遍历数组 a

  3. 处理连续胜利

    • 如果当前比赛赢了(即 a[i] == 1),则增加 sum 的值。
    • 检查是否是连续胜利:如果是连续胜利,从第二场开始每场额外增加1分。
  4. 返回总分数:遍历结束后,返回 sum

关键点

  • 需要一个变量来记录当前连续胜利的场次。
  • 在遇到输的比赛时,重置连续胜利的计数。

关键步骤提示

  1. 初始化连续胜利的计数:在循环外初始化一个变量 consecutiveWins,用于记录当前连续胜利的场次。

  2. 处理连续胜利

    • 如果当前比赛赢了,增加 sum 的值。
    • 增加 consecutiveWins 的值。
    • 如果 consecutiveWins 大于1,表示从第二场开始,每场额外加1分。
  3. 重置连续胜利的计数:如果遇到输的比赛,重置 consecutiveWins 的值。

优化思路

  1. 使用单次遍历:我们只需要一次遍历数组 a,并在遍历过程中维护连续胜利的计数。
  2. 直接计算分数:在遍历过程中,根据连续胜利的场次直接计算分数。

关键点

  1. 维护连续胜利的计数:在遍历过程中,使用 consecutiveWins 变量记录当前连续胜利的场次。
  2. 直接计算分数:每赢一场比赛,分数增加 consecutiveWins,这样可以避免嵌套循环。
  3. 重置连续胜利的计数:遇到输的比赛时,重置 consecutiveWins 为0。

时间复杂度

  • 优化前:O(n^2),因为存在嵌套循环。
  • 优化后:O(n),因为只需要一次遍历数组。
    public static int solution(int n, int[] a) {
        // write code here
        int sum = 0;
        for(int i = 0; i < n; i++){
            if(a[i] == 1){
                sum++;
                for(int j = i + 1; j < n; j++ ){
                    if(a[j] != 1){
                        i = j - 1;
                        break;
                    }
                    sum += 2;
                    if(j == n - 1) i = n - 1; 
                }
            }
        }
        return sum;
    }