870. 优势洗牌(Python)

难度:★★★☆☆
类型:数组
方法:数学

力扣链接请移步本题传送门
更多力扣中等题的解决方案请移步力扣中等题目录

题目

给定两个大小相等的数组 A 和 B,A 相对于 B 的优势可以用满足 A[i] > B[i] 的索引 i 的数目来描述。

返回 A 的任意排列,使其相对于 B 的优势最大化。

示例 1:

输入:A = [2,7,11,15], B = [1,10,4,11]
输出:[2,11,7,15]

示例 2:

输入:A = [12,24,8,32], B = [13,25,32,11]
输出:[24,32,8,12]

提示:

1 <= A.length = B.length <= 10000
0 <= A[i] <= 10^9
0 <= B[i] <= 10^9

解答

这道题实际上是中国的“田忌赛马”,原文如下:

齐使者如梁,孙膑以刑徒阴见,说齐使。齐使以为奇,窃载与之齐。齐将田忌善而客待之。忌数与齐诸公子驰逐重射。孙子见其马足不甚相远,马有上、中、下辈。于是孙子谓田忌曰:“君弟重射,臣能令君胜。”田忌信然之,与王及诸公子逐射千金。及临质,孙子曰:“今以君之下驷彼上驷,取君上驷与彼中驷,取君中驷与彼下驷。”既驰三辈毕,而田忌一不胜而再胜,卒得王千金。于是忌进孙子于威王。威王问兵法,遂以为师。

我们先将两个战队从小到大排序,然后从我们的队伍开始战力从小到大,挑选敌人(假设我们有这个权限),如果我们可以胜过敌人,则派出当前人员参战,否则,我们把当前队员用于对付最强大的敌人,让整体获胜次数最大化。

这里有几点注意:

1.排序时候及时记录敌人的下标,用列表形式保存;
2.这里用enemy_worst, enemy_best两个变量存储当前还没有分配的敌人在排序后数组中的下标;

  1. 将我们的队友添加到敌人列表中建立出战的对应联系。

enemy_team 是包含敌人特定敌人的强弱,对应下标及我方对战队友的三元组。


class Solution(object):
    def advantageCount(self, A, B):
        our_team = sorted(A)
        enemy_team = sorted([v, i] for i, v in enumerate(B))
        enemy_worst, enemy_best = 0, len(B) - 1
        for teammate in our_team:
            enemy, _ = enemy_team[enemy_worst]
            if teammate > enemy:                                # We are confident
                enemy_team[enemy_worst].append(teammate)        # Beat the enemy.
                enemy_worst += 1                                # Select the next worst enemy.
            else:                                               # We are not confident.
                enemy_team[enemy_best].append(teammate)         # Choose the enemy best.
                enemy_best -= 1                                 # Select the next best enemy.
        res = [t[2] for t in sorted(enemy_team, key=lambda x: x[1])]
        return res


A = [2,0,4,1,2]
B = [1,3,0,0,2]
s = Solution()
print(s.advantageCount(A, B))

如有疑问或建议,欢迎评论区留言~

有关更多力扣中等题的python解决方案,请移步力扣中等题解析

你可能感兴趣的:(870. 优势洗牌(Python))