2491-划分技能点相等的团队
给你一个正整数数组 skill
,数组长度为 偶数 n
,其中 skill[i]
表示第 i
个玩家的技能点。将所有玩家分成 n / 2
个 2
人团队,使每一个团队的技能点之和 相等 。
团队的 化学反应 等于团队中玩家的技能点 乘积 。
返回所有团队的 化学反应 之和,如果无法使每个团队的技能点之和相等,则返回 -1
。
示例 1:
**输入:** skill = [3,2,5,1,3,4]
**输出:** 22
**解释:**
将玩家分成 3 个团队 (1, 5), (2, 4), (3, 3) ,每个团队的技能点之和都是 6 。
所有团队的化学反应之和是 1 * 5 + 2 * 4 + 3 * 3 = 5 + 8 + 9 = 22 。
示例 2:
**输入:** skill = [3,4]
**输出:** 12
**解释:**
两个玩家形成一个团队,技能点之和是 7 。
团队的化学反应是 3 * 4 = 12 。
示例 3:
**输入:** skill = [1,1,2,3]
**输出:** -1
**解释:**
无法将玩家分成每个团队技能点都相等的若干个 2 人团队。
提示:
2 <= skill.length <= 105
skill.length
是偶数1 <= skill[i] <= 1000
视频讲解 已出炉,欢迎点赞三连,在评论区分享你对这场周赛的看法~
方法一:排序
如果最小的不和最大的匹配,那么最大的和一个比最小数更大的数匹配,就会导致技能点之和不相等。
因此最小的一定和最大的匹配。
那么排序后模拟即可。
1 | class Solution: |
1 | func dividePlayers(skill []int) (ans int64) { |
复杂度分析
- 时间复杂度:O(n\log n),其中 n 为 skill 的长度。
- 空间复杂度:O(1),忽略排序的栈空间,只用到若干额外变量。
方法二:哈希表
设 total 为 skill 所有数之和,m 为 skill 长度的一半。
那么 total 必须为 m 的倍数,否则返回 -1。
统计 skill 每个数的出现次数,记在哈希表 cnt 中。
设 s=\dfrac{\textit{total} }{m,遍历哈希表,如果 cnt}[x]\ne cnt[s-x],则无法匹配,返回 -1。
否则把 cnt}[x]\cdot x\cdot(s-x) 记到答案中。
最后返回答案的一半(因为重复记录了对称的部分)。
1 | class Solution: |
1 | func dividePlayers(skill []int) (ans int64) { |
复杂度分析
- 时间复杂度:O(n),其中 n 为 skill 的长度。
- 空间复杂度:O(n)。
Comments