870. 优势洗牌:田忌赛马:贪心算法+双指针

简介: 这是 力扣上的 870. 优势洗牌,难度为 中等。

题目描述

这是 力扣上的 870. 优势洗牌,难度为 中等

image.png

题目分析

题目给出的 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 的长度一致

image.png

最终我们期望是达到的 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 结果数组

今天就到这里,若有偏差,还请斧正

欢迎点赞,关注,收藏

朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力

image.png

好了,本次就到这里

技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。

我是阿兵云原生,欢迎点赞关注收藏,下次见~


相关文章
|
28天前
|
JavaScript 前端开发 算法
JavaScript 中通过Array.sort() 实现多字段排序、排序稳定性、随机排序洗牌算法、优化排序性能,JS中排序算法的使用详解(附实际应用代码)
Array.sort() 是一个功能强大的方法,通过自定义的比较函数,可以处理各种复杂的排序逻辑。无论是简单的数字排序,还是多字段、嵌套对象、分组排序等高级应用,Array.sort() 都能胜任。同时,通过性能优化技巧(如映射排序)和结合其他数组方法(如 reduce),Array.sort() 可以用来实现高效的数据处理逻辑。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
28天前
|
JavaScript 算法 前端开发
JS数组操作方法全景图,全网最全构建完整知识网络!js数组操作方法全集(实现筛选转换、随机排序洗牌算法、复杂数据处理统计等情景详解,附大量源码和易错点解析)
这些方法提供了对数组的全面操作,包括搜索、遍历、转换和聚合等。通过分为原地操作方法、非原地操作方法和其他方法便于您理解和记忆,并熟悉他们各自的使用方法与使用范围。详细的案例与进阶使用,方便您理解数组操作的底层原理。链式调用的几个案例,让您玩转数组操作。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
4月前
|
算法 容器
【算法】——双指针算法合集(力扣)
移动零,复写零,快乐数,盛最多水的容器,有效三角形的个数,和为s的两个数(查找总价格为目标值的两个商品 ),三数之和,四数之和
|
10月前
|
算法
双指针算法
双指针算法
68 2
|
10月前
|
机器学习/深度学习 搜索推荐 算法
【再识C进阶2(下)】详细介绍指针的进阶——利用冒泡排序算法模拟实现qsort函数,以及一下习题和指针笔试题
【再识C进阶2(下)】详细介绍指针的进阶——利用冒泡排序算法模拟实现qsort函数,以及一下习题和指针笔试题
115 0
|
6月前
|
存储 算法 安全
ArrayList简介及使用全方位手把手教学(带源码),用ArrayList实现洗牌算法,3个人轮流拿牌(带全部源码)
文章全面介绍了Java中ArrayList的使用方法,包括其构造方法、常见操作、遍历方式、扩容机制,并展示了如何使用ArrayList实现洗牌算法的实例。
52 1
|
7月前
|
算法 索引 容器
双指针算法详解
本文介绍了双指针算法及其应用。双指针算法是在数组或字符串中常用的高效技术,通过维护两个指针遍历数据结构以解决特定问题。根据指针移动方向,可分为同向双指针、相向双指针和快慢指针。同向双指针如移动零和复写零问题;快慢指针如快乐数问题;相向双指针如盛水最多的容器、有效三角形数量及多数之和等问题。通过合理运用双指针技巧,可简化代码并提高效率。
129 4
|
6月前
|
算法 C++
【算法】双指针+二分(C/C++
【算法】双指针+二分(C/C++
|
8月前
|
人工智能 算法 Java
LeetCode经典算法题:井字游戏+优势洗牌+Dota2参议院java解法
LeetCode经典算法题:井字游戏+优势洗牌+Dota2参议院java解法
83 1

热门文章

最新文章