870. 优势洗牌(二分法+双指针)

109 阅读1分钟

image.jpeg

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第21天,点击查看活动详情

测试岗位也越来卷了,除了基本的功能测试外,还要有编程基础、脚本经验才脱颖而出。

怎么才能提高我们的编程能力呢,刷LeetCode是最佳的途径之一,话不多数,刷题走起~

一、题目描述:

  • 题目内容

    image.png

  • 题目示例

    image.png

  • 题目提示

    • 1 <= nums1.length <= 105
    • nums2.length == nums1.length
    • 0 <= nums1[i], nums2[i] <= 109

二、思路分析:

我们今天拿到本题是 leetcode 难度为中等题 870. 优势洗牌。题目要求将nums1对于nums2元素进行优势比较,返回对于nums2优势最大的nums1排序结果。读完简短的题目,有点不明所以...

看完题目网友的补充说明后,题目内容翻译成中文就是田忌赛马,在赛马比赛过程中nums1要取得胜利,则要采取策略用下等马比下等马;下等马比上等马。

  • nums1的最小数大于nums2数时,则nums1与nums2元素匹配
  • nums1的num数小于num2的数时,将nums1的最小数拿去与nums2的最大数匹配
  • nums2数组的元素不能排序,因此需要辅助变量来排序

根据题目内容理解,我们可以使用二分查找和双指针方法来解答该题,思路如下:

  • 方法一:二分法

    • 对于nums1的元素按照升序排序处理得到sortnum1
    • 循环遍历nums2每个元素,二分法在nums1中距离nums2[i]较近的索引位置pos
    • 如果pos位置大于sortnum1的长度,则num1中元素都不大于nums2元素,则选择nums1中元素与其配对,推出索引位置0的数添加到ans列表
    • 如果pos位置小于sortnum1的长度,则num1的元素大于num2的元素,则将pos位置上推出,冰将添加到ans列表
    from sortedcontainers import SortedList
    class Solution(object):
        def advantageCount(self, nums1, nums2):
            """
            :type nums1: List[int]
            :type nums2: List[int]
            :rtype: List[int]
            """
            ans = []
            # sortnum1 = SortedList(nums1)
            sortnum1 = sorted(nums1)
            for i in range(len(nums2)):
                # pos = sortnum1.bisect_right(nums2[i])
                pos = bisect_right(sortnum1,nums2[i])
                if pos < len(sortnum1):
                    num = sortnum1.pop(pos)
                else:
                    num = sortnum1.pop(0)
                ans.append(num)
            return ans
    
  • 方法二:双指针

    • 对nums1元素提前进行升序排序,并引入临时列表idex2根据nums2元素进行索引排序
    • 定义left和right两指针指向nums2的索引排序数组idex2首尾
    • 遍历nums1元素,num1的最小元素大于num2的最小元素时,则匹配完成,ans[idex2[left]]赋值为num,left指针向右移动一步
    • 当num1的元素小于num2元素时,则将与nums2的最大数right匹配,ans[idex2[right]]赋值为num,right指针向左移动一步
    class Solution(object):
        def advantageCount(self, nums1, nums2):
            """
            :type nums1: List[int]
            :type nums2: List[int]
            :rtype: List[int]
            """
            n = len(nums1)
            nums1.sort()
            idex2 = list(range(n))
            idex2.sort(key=lambda x:nums2[x])
            ans = [0]*n
            left,right = 0,n-1
            for num in nums1:
                if num > nums2[idex2[left]]:
                    ans[idex2[left]]= num
                    left +=1
                else:
                    ans[idex2[right]]= num
                    right -=1
    
            return ans
    

三、总结:

本题是一道关于策略制定的题,想要在比较过程获得更大优势,将自己最小值大于对方最小值或者自己最小值小于对方最小值则与对方最大值匹配,这样策略对于自己优势比较大。AC提交记录如下:

image.png

  • 时间复杂度:O(nlogn),n为nums1的长度
  • 空间复杂度:O(n),需要使用额外空间进行索引排序

以上是本期内容,欢迎大佬们点赞评论,下期见~~~