「这是我参与2022首次更文挑战的第8天,活动详情查看:2022首次更文挑战」。
题目描述
给你一个整数 n ,表示比赛中的队伍数。比赛遵循一种独特的赛制:
如果当前队伍数是 偶数 ,那么每支队伍都会与另一支队伍配对。总共进行 n / 2 场比赛,且产生 n / 2 支队伍进入下一轮。 如果当前队伍数为 奇数 ,那么将会随机轮空并晋级一支队伍,其余的队伍配对。总共进行 (n - 1) / 2 场比赛,且产生 (n - 1) / 2 + 1 支队伍进入下一轮。 返回在比赛中进行的配对次数,直到决出获胜队伍为止。
示例 1:
输入:n = 7
输出:6
解释:比赛详情:
- 第 1 轮:队伍数 = 7 ,配对次数 = 3 ,4 支队伍晋级。
- 第 2 轮:队伍数 = 4 ,配对次数 = 2 ,2 支队伍晋级。
- 第 3 轮:队伍数 = 2 ,配对次数 = 1 ,决出 1 支获胜队伍。
总配对次数 = 3 + 2 + 1 = 6
思路分析
最简单的就是模拟的方式,按照他的方式进行配对与晋级。偶数时减半,并加上这部分值,奇数时减半+1,因为有一个人轮空,所以7人比赛会和8人比赛一个结果,但是此时比赛数只有3次,因此需要ret += n - 1
int numberOfMatches(int n) {
int ret = 0;
while(n > 1){
if (n % 2 == 0){
// 偶数
n = n / 2;
ret += n;
}else{
// 奇数
n = n / 2 + 1;
ret += (n - 1);
}
}
return ret;
}
但理论上应该还有数学方法可以优化,至少我们发现,每次偶数时ret增加的值都是它本身/2,每次奇数时增加的值也都是他➗2【但是n整体其实是➗2+1的】,因此这个思路没法正向算,我们可以反过来想:每次比赛淘汰一个选手,总共淘汰n-1个选手,因此总共有n-1次比赛。
int numberOfMatches(int n) {
return n -1;
}
难不成还可以继续优化?
查看了前100%的题解发现答案和我的提交一样。