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

好了,本次就到这里

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

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


相关文章
|
5月前
|
算法
双指针算法
双指针算法
31 2
|
2月前
|
算法 索引 容器
双指针算法详解
本文介绍了双指针算法及其应用。双指针算法是在数组或字符串中常用的高效技术,通过维护两个指针遍历数据结构以解决特定问题。根据指针移动方向,可分为同向双指针、相向双指针和快慢指针。同向双指针如移动零和复写零问题;快慢指针如快乐数问题;相向双指针如盛水最多的容器、有效三角形数量及多数之和等问题。通过合理运用双指针技巧,可简化代码并提高效率。
62 4
双指针算法详解
|
5月前
|
机器学习/深度学习 搜索推荐 算法
【再识C进阶2(下)】详细介绍指针的进阶——利用冒泡排序算法模拟实现qsort函数,以及一下习题和指针笔试题
【再识C进阶2(下)】详细介绍指针的进阶——利用冒泡排序算法模拟实现qsort函数,以及一下习题和指针笔试题
|
1月前
|
算法 C++
【算法】双指针+二分(C/C++
【算法】双指针+二分(C/C++
|
1月前
|
存储 算法 安全
ArrayList简介及使用全方位手把手教学(带源码),用ArrayList实现洗牌算法,3个人轮流拿牌(带全部源码)
文章全面介绍了Java中ArrayList的使用方法,包括其构造方法、常见操作、遍历方式、扩容机制,并展示了如何使用ArrayList实现洗牌算法的实例。
15 0
|
3月前
|
人工智能 算法 Java
LeetCode经典算法题:井字游戏+优势洗牌+Dota2参议院java解法
LeetCode经典算法题:井字游戏+优势洗牌+Dota2参议院java解法
50 1
|
3月前
|
算法 容器
【算法】双指针
【算法】双指针
|
3月前
|
算法 C++ 容器
【C++算法】双指针
【C++算法】双指针
|
6月前
|
存储 算法 容器
ArrayList | 简单的洗牌算法
这是一个关于创建和洗牌扑克牌程序的摘要: 程序包括以下步骤: 1. 创建一副扑克牌(52张,不包括大小王)。 2. 洗牌,随机打乱扑克牌的顺序。 3. 揭牌,模拟玩家轮流从牌堆中抽取指定数量的牌。
51 4