一、题目
给定两个大小相等的数组 nums1 和 nums2,nums1 相对于 nums 的优势可以用满足 nums1[i] > nums2[i] 的索引 i 的数目来描述。
返回 nums1 的任意排列,使其相对于 nums2 的优势最大化。
也就是说针对数组2中的每个元素,如果在数组1中有比其大的则建立连接(使其索引相同),如果没有更大的,则使用数组1中最小的元素与其建立连接,达到田忌赛马,中等马对下等马,下等马对上等马的目的。
二、思路
针对两个数组进行递增排序。 注:此处排序想要得到的不是递增数组本身,而是递增数组元素在原数组中的索引数组。
此时,nums1和nums2为递增数组,将两个数组进行比较:
1. 中等马对下等马:如果nums1中的首个元素大于nums2中的首个元素,由于nums1中的首个元素是整个数组中的最小元素,则是最小解最优解,那么建立连接,并移除两个比较元素(因为已经建立好连接,不需要继续比较)。
2.下等马对上等马:如果nums1中的首个元素小于nums2中的首个元素,说明该元素小于nums2中的所有元素(因为是nums2中的最小元素),同时也说明nums2中必有一个元素是大于nums1中所有元素的,因为nums1和2数量相等。所以此时将1中该元素与2中最大的元素建立连接,删除两个元素。
注意点:
在循环比较时nums2需要使用循环外设置的left和right指针,双指针不能随着循环的进行随意增加,必须要满足某一匹配条件时才能变动。
三、实现
def advantageCount(self, nums1: List[int], nums2: List[int]) -> List[int]:
size = len(nums1)
s1 = list(range(size))
s2 = list(range(size))
s1.sort(key = lambda x: nums1[x])
s2.sort(key = lambda x: nums2[x])
left = 0
right = size - 1
nums = [0]*size
for i in range(size):
if nums1[s1[i]] > nums2[s2[left]]:
nums[s2[left]] = nums1[s1[i]]
left += 1
else:
nums[s2[right]] = nums1[s1[i]]
right -= 1
return nums
首先定义s1,s2,内容是0~size的连续序列,意为原数组的默认递增索引。
然后根据nums1和2中的值,对索引进行排序,这样既能对nums1和nums2进行排序,又能保存原来的顺序。
设置双指针left和right用于比较nums2中的值。
定义nums数组接受结果。
在循环里,遍历s1数组,根据nums1中的值与双指针指向的nums2数组中的值进行比较,如果nums1最小值大于nums2最小值,建立连接,left指针后移(意为移除nums2中的最小元素)。
如果nums1最小值小于nums2最小值,与right指针指向的nums2中最大元素建立连接,right指针左移(意为移除nums2中最大元素)。
注:因为在每次比较中,无论如何nums1中的最小元素都会被消除,所以可以使用for循环中的i直接遍历,而每次比较中消除的nums2中的元素可能是最大元素也可能是最小元素,所以使用双指针进行消除。