问题描述
小R正在组织一个比赛,比赛中有 n 支队伍参赛。比赛遵循以下独特的赛制: 如果当前队伍数为 偶数,那么每支队伍都会与另一支队伍配对。总共进行 n 2场比赛,且产生 n 2 支队伍进入下一轮。 如果当前队伍数为 奇数,那么将会随机轮空并晋级一支队伍,其余的队伍配对。 总共进行(n - 1) / 2 场比赛,且产生(n - 1) /2 + 1支队伍进入下一轮。 小R想知道在比赛中进行的配对次数,直到决出唯一的获胜队伍为止。
测试样例
样例1:
输入:n = 7输出: 6
样例2:
输入: n = 14输出:13
样例3:
输入: n = 1输出: 0
问题理解
你需要计算在比赛中进行的配对次数,直到决出唯一的获胜队伍为止。比赛规则如下:
- 如果当前队伍数为偶数,每支队伍都会与另一支队伍配对,进行
n / 2场比赛,产生n / 2支队伍进入下一轮。 - 如果当前队伍数为奇数,随机轮空并晋级一支队伍,其余的队伍配对,进行
(n - 1) / 2场比赛,产生(n - 1) / 2 + 1支队伍进入下一轮。
解题思路
-
初始队伍数:从
n开始。 -
循环处理每一轮:
- 如果当前队伍数为偶数,进行
n / 2场比赛,剩余n / 2支队伍。 - 如果当前队伍数为奇数,进行
(n - 1) / 2场比赛,剩余(n - 1) / 2 + 1支队伍。
- 如果当前队伍数为偶数,进行
-
累计比赛次数:每次配对时,将配对次数累加到总次数中。
-
终止条件:当队伍数减少到 1 时,比赛结束。
代码如下:
def solution(n: int) -> int:
total_matches = 0
while n > 1:
if n % 2 == 0:
# 偶数队伍,每场比赛消除一个队伍
matches = n // 2
n = n // 2 # 剩下的队伍数
else:
# 奇数队伍,一个队伍轮空,其他队伍进行比赛
matches = (n - 1) // 2
n = (n - 1) // 2 + 1 # 剩下的队伍数,包含轮空的一个队伍
total_matches += matches # 累加当前轮的比赛数
return total_matches
if __name__ == '__main__':
print(solution(7) == 6)
print(solution(14) == 13)
print(solution(1) == 0)
关键步骤
-
初始化总比赛次数:
total_matches = 0。 -
循环处理每一轮:
- 判断当前队伍数是奇数还是偶数。
- 计算当前轮的比赛次数
matches。 - 更新剩余队伍数
n。 - 累加当前轮的比赛次数到总比赛次数
total_matches。
-
返回总比赛次数。
复杂度分析
- 时间复杂度: 由于每轮比赛队伍数都会减半,时间复杂度为
O(log n)。 - 空间复杂度: 由于只使用了常数空间存储比赛数和队伍数,空间复杂度为
O(1)。