问题描述
小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 来存储比赛结果。
算法步骤
-
初始化总分数:用一个变量
sum来记录总分数,初始值为0。 -
遍历比赛结果数组:使用一个循环遍历数组
a。 -
处理连续胜利:
- 如果当前比赛赢了(即
a[i] == 1),则增加sum的值。 - 检查是否是连续胜利:如果是连续胜利,从第二场开始每场额外增加1分。
- 如果当前比赛赢了(即
-
返回总分数:遍历结束后,返回
sum。
关键点
- 需要一个变量来记录当前连续胜利的场次。
- 在遇到输的比赛时,重置连续胜利的计数。
关键步骤提示
-
初始化连续胜利的计数:在循环外初始化一个变量
consecutiveWins,用于记录当前连续胜利的场次。 -
处理连续胜利:
- 如果当前比赛赢了,增加
sum的值。 - 增加
consecutiveWins的值。 - 如果
consecutiveWins大于1,表示从第二场开始,每场额外加1分。
- 如果当前比赛赢了,增加
-
重置连续胜利的计数:如果遇到输的比赛,重置
consecutiveWins的值。
优化思路
- 使用单次遍历:我们只需要一次遍历数组
a,并在遍历过程中维护连续胜利的计数。 - 直接计算分数:在遍历过程中,根据连续胜利的场次直接计算分数。
关键点
- 维护连续胜利的计数:在遍历过程中,使用
consecutiveWins变量记录当前连续胜利的场次。 - 直接计算分数:每赢一场比赛,分数增加
consecutiveWins,这样可以避免嵌套循环。 - 重置连续胜利的计数:遇到输的比赛时,重置
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;
}