题目描述
这是 力扣上的 870. 优势洗牌,难度为 中等。
题目分析
题目给出的 nums1 和 nums2 ,要我们从 nums1 中找到大于 nums2 的数,并逐个配对,找出让 nums1 优势最大的配对情况
对于这个情况隐隐约约是想到了小学学的田忌赛马,没想到今天还用上了,如果不知道这个典故的,可以自行搜索
对于分析这个题,咱们是可以知道,其实就是在 nums1 中找到尽可能多的数字比 nums2 中的数字大,那么我们可以这样来找:
将 nums1 和 nums2 进行从小到大排序,如果 nums1 的第一个元素,是大于 nums2 的第一个元素,那么自然是 nums1 的优势就可以增长一点了
然后再继续遍历 nums1 ,如果是发现 nums1 的值是小于 nums2 的值的,那么说明当前 nums1 的值,对于 nums2 没有一点优势了,那么就用当前 nums1 的值,去和 nums2 最大的一个值去做配对吧
那么问题来了?如何去和 nums2 进行 配对呢?
此处我们需要注意, nums2 数组,咱们是不能去修改他的原值的,通过题目中给出的实例其实我们就可以知道
因此,咱们需要去对 nums2 的索引来进行排序,排序的条件是 nums2 中数据,例如索引数组是 idx,长度和 nums1 的长度一致
最终我们期望是达到的 idx 数组的索引 0 是对应着 nums2 数组中的最小值
idx 数组的索引 1 对应着 nums2 的次小值
这样的话,我们就可以使用双指针的方式,令 nums2 的左边索引为 left=0,右边索引为 right=len(nums2)
按照上述逻辑,咱们就可以从 idx 索引容易的获取 nums2 的最小值,最大值,并逐个和 nums1 来进行比较了
接下来,咱们就可以来实现编码了,咱们这次使用 golang 的方式来进行实现
Golang 的实现方式:
- 对 nums1 进行排序
- 新建 idx 索引,对索引排序,排序依据是 nums2 中的数据
- 定义双指针 left 和 rigth 分别代表索引指向对于 nums2 的最小值和最大值,遍历 nums1 ,逐个和 nums2 进行比较,若 nums1 的数据大,则将 nums1 的数据 放到 ans 中 和 nums2 left 对应的索引上,反之,就把 nums1 的数据,放到 nums right 对应的索引上
func advantageCount(nums1 []int, nums2 []int) []int { // 这就相当于是田忌赛马,这个故事咱们学生时代已经是学过的 // 相当于咱们就看 nums1 的最小值 是否是大于 nums 2 的最小值,如果是那么就ok,继续比较 // 如果不是,则nums1 当前的这个值不可能再比 nums2 的任意值大了,因此,直接去和 nums2 的最大值比较对上就好了 n := len(nums1) ans := make([]int, n) sort.Ints(nums1) idx := make([]int, n) for index := range idx { idx[index] = index } // 此处咱们的索引是 0-0 1-1 。。。 // 我们对索引排序,排序的条件是 nums2 中的数据 sort.Slice(idx, func(i,j int)bool{ return nums2[idx[i]] < nums2[idx[j]] }) left,right := 0, n-1 for i := range nums2 { if nums1[i] > nums2[idx[left]]{ ans[idx[left]] = nums1[i] left++ }else{ ans[idx[right]] = nums1[i] right-- } } return ans }
这种实现方式,咱们的时间复杂度是 O(nlogn) ,因为咱们使用了排序,此处的 n 是 nums1 的长度,空间复杂度是 O(n) ,咱们开辟了 ans 结果数组
今天就到这里,若有偏差,还请斧正
欢迎点赞,关注,收藏
朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力
好了,本次就到这里
技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。
我是阿兵云原生,欢迎点赞关注收藏,下次见~