leetcode
leetcode 2151 ~ 2200
划分技能点相等的团队

划分技能点相等的团队

难度:

标签:

题目描述

You are given a positive integer array skill of even length n where skill[i] denotes the skill of the ith player. Divide the players into n / 2 teams of size 2 such that the total skill of each team is equal.

The chemistry of a team is equal to the product of the skills of the players on that team.

Return the sum of the chemistry of all the teams, or return -1 if there is no way to divide the players into teams such that the total skill of each team is equal.

 

Example 1:

Input: skill = [3,2,5,1,3,4]
Output: 22
Explanation: 
Divide the players into the following teams: (1, 5), (2, 4), (3, 3), where each team has a total skill of 6.
The sum of the chemistry of all the teams is: 1 * 5 + 2 * 4 + 3 * 3 = 5 + 8 + 9 = 22.

Example 2:

Input: skill = [3,4]
Output: 12
Explanation: 
The two players form a team with a total skill of 7.
The chemistry of the team is 3 * 4 = 12.

Example 3:

Input: skill = [1,1,2,3]
Output: -1
Explanation: 
There is no way to divide the players into teams such that the total skill of each team is equal.

 

Constraints:

  • 2 <= skill.length <= 105
  • skill.length is even.
  • 1 <= skill[i] <= 1000

代码结果

运行时间: 55 ms, 内存: 26.3 MB


/*
思路:
1. 使用Stream对技能点数组进行排序。
2. 将排序后的数组划分为两部分,使用IntStream分别从头和尾部配对。
3. 检查每个团队的技能点之和是否相等,如果不相等则返回-1。
4. 如果相等,计算团队的化学反应(技能点乘积)并累加。
*/

import java.util.Arrays;
import java.util.stream.IntStream;

public class Solution {
    public int teamChemistry(int[] skill) {
        Arrays.sort(skill); // 对数组进行排序
        int n = skill.length;
        int sum = skill[0] + skill[n - 1]; // 预期的技能点之和
        int chemistry = IntStream.range(0, n / 2) // 从0到n/2
                .map(i -> {
                    int teamSum = skill[i] + skill[n - 1 - i];
                    if (teamSum != sum) {
                        throw new IllegalArgumentException("不匹配"); // 如果有团队的技能点之和不等于预期值,抛出异常
                    }
                    return skill[i] * skill[n - 1 - i]; // 返回团队的化学反应
                }).sum(); // 累加化学反应
        return chemistry; // 返回所有团队的化学反应之和
    }
}

解释

方法:

该题解通过先对技能点数组进行排序,然后尝试将最小的元素和最大的元素配对,第二小的元素与第二大的元素配对,以此类推,形成团队。这种配对方式旨在通过将极端值配对来平衡团队的技能点之和,以期望每个团队的技能点之和都相等。如果在配对过程中发现某一对的技能点之和与之前的不同,则返回-1,表明无法形成要求的团队。如果所有配对的技能点之和都相等,则计算每个团队的化学反应(即技能点的乘积),并计算总和返回。

时间复杂度:

O(n log n)

空间复杂度:

O(1)

代码细节讲解

🦆
为什么在解决问题时选择将数组排序再配对而不是其他方法?
排序然后配对数组的最小元素和最大元素的方法可以帮助平衡团队的技能点之和。通过这种方式,可以最大化地减少每对团队间技能点之和的差异,理论上更有可能达到所有团队技能点之和相等的目标。此外,排序后的配对策略可以简化问题,使得算法更易实现和理解。未排序的配对可能需要复杂的逻辑来确保所有团队的技能点之和相等,而且计算复杂度可能更高。
🦆
排序后直接配对最小元素和最大元素的方法是否总能保证所有团队的技能点之和相等?
这种方法并不能保证所有团队的技能点之和总是相等。这种配对策略是一种启发式方法,它在某些情况下能够工作,尤其是当数组元素能够很好地互补时。然而,如果数组中的数值差异较大或分布不均,这种方法可能无法使所有团队的技能点之和相等。在这种情况下,算法会检测到不一致并返回-1,表示无法按要求分配团队。
🦆
在实现中,如果在某一对中发现技能点之和不符合要求,直接返回-1,这种方法是否可能忽略了其他可能的配对方式?
是的,这种方法可能会忽略其他可能的配对方式。算法依赖于排序后的简单配对策略,即将最小的元素与最大的元素配对,这种方式在发现第一个不符合条件的配对时就会终止并返回-1。这意味着算法没有考虑重新排列或选择不同配对策略的可能性,可能存在其他的配对顺序可以满足所有团队技能点之和相等的条件。然而,探索所有可能的配对方式将大大增加算法的复杂性和执行时间。

相关问题