问题描述
小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
题目分析:
1.比赛规则
小R的比赛有以下特点:
1.每轮比赛的队伍总数 n 决定比赛场次:
- 如果 n 为 偶数,所有队伍两两配对,进行 n/2 场比赛,获胜的 n/2 支队伍进入下一轮,
- 如果 n 为 奇数,随机轮空一支队伍直接晋级,其余队伍两两配对,进行(n - 1)/2 场比 赛。进入下一轮的队伍总数为(n -1)/2+1; 2.比赛持续进行,队伍总数逐轮减少,直到仅剩一支队伍为止。
2.目标
计算在整个比赛过程中,总共进行了多少场配对比赛。
解题思路:
1.每轮比赛的计算公式
每轮的比赛场次是当前队伍数 n 的整除结果:
- 如果 n 是偶数,比赛场次为 n/2;
- 如果 n 是奇数,比赛场次为(n-1)/2(等价于n//2)
同时,下一轮的队伍数更新规则为:n=n//2+n%2
- n//2 表示配对比赛的获胜队伍数;
- n%2 表示当 n 为奇数时轮空直接晋级的队伍。
2.终止条件
比赛会持续进行,直到几=1(剩下一支队伍时结束)
3.总比赛场次累加
我们用一个变量 count来累计每轮的比赛场次,直到比赛结束
4.简化观寨
在整个比赛中,每次减少的队伍数量等于比赛场次,而队伍总数几会逐步减少到 1。因此
- 比赛场次的总和等于原始队伍数 n 减去1(最终剩余的唯一队伍)。
解题步骤
1.理解题目规则
每轮比赛规则可直接归纳为:配对数 =n//2,并更新队伍数为 n= n//2 +n%2。
2.初始化变量
设 count 为总配对次数,初始值为 0。
3.模拟比赛过程
- 在循环中,计算当前轮配对数,累加到count;
- 更新队伍数 n,模拟进入下一轮;
- 当 n ==1 时,跳出循环。
4.返回结果
输出 count,即比赛中进行的总配对次数。
代码实现:
def solution(n: int) -> int:
# 初始化配对次数
count = 0
# 模拟比赛过程
while n > 1:
count += n // 2 # 当前轮比赛场次
n = n // 2 + n % 2 # 更新剩余队伍数
return count
复杂度分析:
1.时间复杂度:O(log n)
每轮队伍数减少到原来的一半,最多需要 log n 轮。
2.空间复杂度:O(1)
仅使用常量变量 count 和n。
直观公式化观察:
对于任意队伍数 ,总比赛场次等于所有被淘汰队伍数:
- 比赛淘汰n-1支队伍,剩余1支获胜;
- 所以总比赛场次是n-1。