问题描述
小M参加了一场n个人的比赛,比赛规则是所有选手两两对决。每个人有一个能力值,对应着他们的序号。参赛者同时被分为黄色或蓝色两种颜色。比赛胜负的规则如下:
- 当比赛双方颜色不同时,能力值大的选手获胜;
- 当比赛双方颜色相同时,能力值较小的选手获胜。
你需要帮助小M计算每个选手在比赛中能赢得的场数。
测试样例
样例1:
输入:
n = 3, a = [0, 0, 1]
输出:[1, 0, 2]
样例2:
输入:
n = 4, a = [1, 0, 1, 0]
输出:[1, 2, 1, 2]
样例3:
输入:
n = 5, a = [0, 1, 0, 1, 0]
输出:[2, 2, 2, 2, 2]
题目解析
解题思路
-
理解比赛规则:
- 颜色不同:能力值大的选手获胜。
- 颜色相同:能力值小的选手获胜。
-
正确比较能力值:
- 能力值就是选手的索引
i和j。 - 在颜色不同的情况下,直接比较索引
i和j的大小。 - 在颜色相同的情况下,直接比较索引
i和j的大小。
- 能力值就是选手的索引
算法步骤
-
初始化胜场数组:
int[] wins = new int[n];创建一个长度为n的数组wins,用于记录每个选手的胜场数。
-
遍历所有可能的对决:
- 使用两层循环遍历所有可能的选手对
(i, j),其中i < j。
- 使用两层循环遍历所有可能的选手对
-
根据比赛规则更新胜场数:
- 如果
a[i] != a[j](颜色不同),比较能力值(即索引i和j),能力值大的选手胜场数加一。 - 如果
a[i] == a[j](颜色相同),比较能力值(即索引i和j),能力值小的选手胜场数加一。
- 如果
解释:
-
初始化胜场数组:首先,我们创建一个
wins[]数组,它的长度为n,并且初始化每个元素为 0,表示每个选手初始时没有胜场。 -
双重循环遍历所有对战对:
- 外层循环
i遍历所有选手。 - 内层循环
j遍历从i+1到n-1的选手,这样每对(i, j)只处理一次。
- 外层循环
-
比赛规则判断:
- 颜色不同:如果
a[i] != a[j],则比较i和j的大小,能力值大的选手获胜。 - 颜色相同:如果
a[i] == a[j],则比较i和j的大小,能力值小的选手获胜。
- 颜色不同:如果
-
更新胜场数:根据比赛规则更新每个选手的胜场数。
-
返回结果:函数返回更新后的
wins[]数组,其中每个元素表示对应选手的胜场数。
时间复杂度:
- 外层和内层循环的总次数是
O(n^2),其中n是选手的数量,因此时间复杂度为O(n^2)。
代码实现
import java.util.Arrays;
public class Main {
public static int[] solution(int n, int[] a) {
// write code here
int[] wins = new int[n];
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
if(a[i]!=a[j]){
if(i > j) wins[i]++;
else wins[j]++;
}
if (a[i] == a[j]) {
if(i < j) wins[i]++;
else wins[j]++;
}
}
}
return wins;
}
public static void main(String[] args) {
System.out.println(Arrays.equals(solution(3, new int[]{0, 0, 1}), new int[]{1, 0, 2}));
System.out.println(Arrays.equals(solution(4, new int[]{1, 0, 1, 0}), new int[]{1, 2, 1, 2}));
System.out.println(Arrays.equals(solution(5, new int[]{0, 1, 0, 1, 0}), new int[]{2, 2, 2, 2, 2}));
}
}