20.比赛配对问题 题目解析
问题描述:
小R组织了一场比赛,有 nn 支队伍参赛,遵循以下规则:
- 如果当前队伍数 n 是偶数,所有队伍两两配对,总共 n/2 场比赛,剩下 n/2 支队伍晋级。
- 如果当前队伍数 n 是奇数,随机轮空一支队伍晋级,其余队伍配对,总共 (n−1)/2 场比赛,剩下 (n−1)/2+1 支队伍晋级。
- 比赛持续进行,直到决出唯一获胜队伍。
目标是计算比赛总共进行了多少场配对比赛。
解题思路
规则分析:
- 每轮比赛的配对数由当前队伍数 n 决定:
- 如果 n 是偶数,配对数为 n/2。
- 如果 n是奇数,配对数为 (n−1)/2。
- 无论队伍是奇数还是偶数,下一轮的队伍数总是 n//2 或 n//2+1,随着比赛轮次的增加,队伍数逐渐减少。
- 比赛会持续进行,直到只剩下一支队伍。
算法设计:
- 用一个变量
matches累加配对次数。 - 当队伍数 n>1 时,根据奇偶性分别计算配对数和下一轮的队伍数,更新 n。
- 最后返回总配对次数
matches。
时间复杂度:
每轮队伍数减半,时间复杂度为 O(logn)。
代码实现
def solution(n: int) -> int:
matches = 0
while n > 1: # 当队伍数大于1时继续比赛
if n % 2 == 0: # 偶数情况
matches += n // 2
n = n // 2
else: # 奇数情况
matches += (n - 1) // 2
n = (n - 1) // 2 + 1
return matches
if __name__ == '__main__':
# 测试样例
print(solution(7) == 6) # True
print(solution(14) == 13) # True
print(solution(1) == 0) # True
总结
- 算法关键:按奇偶性计算每轮配对次数,并更新队伍数直到只剩一支队伍。
- 复杂度:
- 时间复杂度:O(logn)(每轮队伍数减半)。
- 空间复杂度:O(1)(只使用常量变量)。
- 适用场景:适合计算任意单淘汰赛制下的总比赛场次,高效简洁。
21 环形数组中的最大贡献值 题目解析
问题描述
小S拥有一个长度为 n 的环形数组 a,要求在所有可能的下标对 (i,j)中,找到贡献值公式:
dist(i,j) 是环形数组中 i和 j 的最短距离,计算公式为:
环形数组特点
- 相邻特性:数组首尾相接,即 a[0] 与 a[n−1]也算相邻。
- 距离特性:两点之间的最短距离可能通过正向或逆向路径决定。
目标
遍历所有下标对 (i,j),计算每对的贡献值 f(i,j)),并返回最大值。
解题思路
暴力解法
- 遍历所有 (i,j)) 配对,计算对应的贡献值:
- 两层嵌套循环:
- 外层遍历 i,范围为 0 到 n−1。
- 内层遍历 j,范围为 i+1 到 n−1。
- 计算每对的距离 dist(i,j) 和贡献值 f(i,j)。
- 两层嵌套循环:
- 使用变量记录当前的最大贡献值。
- 返回最大值。
优化点
- 复杂度:暴力解法的时间复杂度为 O(n^2),适用于小规模 n 的数组。如果 n 较大,需要进一步优化。
代码实现
def solution(n: int, a: list) -> int:
max_contribution = float('-inf')
# 遍历所有可能的 i, j 配对
for i in range(n):
for j in range(i + 1, n):
# 计算 i 和 j 之间的最短距离
dist = min(j - i, n - (j - i))
# 计算贡献值
contribution = (a[i] + a[j]) * dist
# 更新最大贡献值
max_contribution = max(max_contribution, contribution)
return max_contribution
if __name__ == '__main__':
print(solution(3, [1, 2, 3]) == 5) # 测试样例1
print(solution(4, [4, 1, 2, 3]) == 12) # 测试样例2
print(solution(5, [1, 5, 3, 7, 2]) == 24) # 测试样例3
复杂度分析
- 时间复杂度:两层循环遍历所有 (i,j),复杂度为 O(n^2)。
- 空间复杂度:只使用常量变量,复杂度为 O(1)。
优化思路
在暴力解法的基础上,可以通过如下方法优化:
- 预计算距离矩阵:预先计算每对下标的距离以减少重复计算。
- 空间换时间:对贡献值的性质进行分析,减少不必要的比较。
对于较大规模的 n,需要针对性优化以降低时间复杂度。