题目描述
给定两个大小相等的数组 n u m s 1 nums1 nums1 和 n u m s 2 nums2 nums2, n u m s 1 nums1 nums1 相对于 n u m s 2 nums2 nums2的优势可以用满足 n u m s 1 [ i ] nums1[i] nums1[i] > n u m s 2 [ i ] nums2[i] nums2[i] 的索引 i i i 的数目来描述。
返回 n u m s 1 nums1 nums1 的任意排列,使其相对于 n u m s 2 nums2 nums2 的优势最大化。
样例输入
示例1
输入:nums1 = [2,7,11,15], nums2 = [1,10,4,11]
输出:[2,11,7,15]
示例2
输入:nums1 = [12,24,8,32], nums2 = [13,25,32,11]
输出:[24,32,8,12]
田忌赛马式解题思路:
今以君之下驷与彼上驷,取君上驷与彼中驷,取君中驷与彼下驷。”既驰三辈毕,而田忌一不胜而再胜,卒得王千金。
田忌赛马的故事大家都听说过,简而言之就是发挥每匹优势马的最大效力,并且使用劣势马去消耗对方优势马。
使用相同的策略,我们可以把 n u m s 1 nums1 nums1作为田忌的马群,把 n u m s 2 nums2 nums2作为齐威王的马群,并遵循以下原则作为 n u m s 1 nums1 nums1的上场顺序准则:
- 首先将两组马群按照脚力小大升序排列,每次派出顺序队列中的一匹马上场;
- 如果 n u m s 1 nums1 nums1中的马匹 x x x脚力比得过 n u m s nums nums中的马匹 y y y,那么就确定使用当前马匹 x x x作为1的优势马匹从前顺序排列,即 a n s [ l e f t ] = x ans[left]=x ans[left]=x;
- 如果 n u m s 1 nums1 nums1中的马匹 x x x脚力比不过 n u m s nums nums中的马匹 y y y,那么就确定使用当前马匹 x x x作为1的劣势马匹从后顺序,即 a n s [ r i g h t ] = x ans[right]=x ans[right]=x;
如此一来,
n
u
m
s
1
nums1
nums1中的每匹马都可以根据自身脚力发挥最大效力,并且这是一个可用程序迭代的过程。
唯一需要说明的一点:
n
u
m
s
2
nums2
nums2中的马匹出战顺序不可再更改,所以要用额外的索引数组对其顺序进行标记,使每次与
n
u
m
s
1
nums1
nums1比较的马匹都是顺序递增的。
代码
from typing import List
class Solution:
def advantageCount(self, nums1: List[int], nums2: List[int]) -> List[int]:
ans=[0 for i in range(len(nums1))]
# 比较取巧的idx数组,解决了nums2顺序索引的问题
idx = sorted(range(len(nums1)),key=lambda i:nums2[i])
nums1.sort()
left,right=0,len(nums2)-1
for i,num in enumerate(nums1):
# print("第{}次比较过程:".format(i))
# 优势马对应的情况
if num>nums2[idx[left]]:
# print("当前使用nums1中的{}与nums2中索引为{}的{}比较".format(num,idx[left],nums2[idx[left]]))
ans[idx[left]]=num
left+=1
# 劣势马对应的情况
else:
# print("当前使用nums1中的{}与nums2中索引为{}的{}比较".format(num, idx[right], nums2[idx[right]]))
ans[idx[right]]=num
right-=1
return ans
if __name__ == '__main__':
nums1 = [2, 7, 11, 15]
nums2 = [1, 10, 4, 11]
print(Solution().advantageCount(nums1, nums2))