【Leetcode】2576. 求出最多标记下标_1843

题目

2576. 求出最多标记下标

给你一个下标从 0 开始的整数数组 nums 。

一开始,所有下标都没有被标记。你可以执行以下操作任意次:

选择两个 互不相同且未标记 的下标 i 和 j ,满足 \(2 * nums[i] <= nums[j]\) ,标记下标 i 和 j 。
请你执行上述操作任意次,返回 nums 中最多可以标记的下标数目。

  • \(1<=nums.length<=10^5\)

思路

首先看到题目是匹配尽可能多的\(2 * nums[i] <= nums[j]\),那么根据这个可以发现的是,对于任意匹配,选择nums[i]较小的值,总是不差于选择更大的nums[i]

换句话说,倘若更大的nums[i]可以完成匹配,那么较小的nums[i]就一定可以完成匹配。

既然存在着大小关系的说明,那么就首先对数组进行排序。

因此,对于整个数组而言,能够得到最优解的基础上,可能的nums[i]就是数组的前半段。同样的可以证明的是,在次规则的基础上,可能的nums[j]就是数组的后半段,而且随着nums[i]匹配的进行,与之匹配的nums[j]也会随着增大。因此考虑使用双指针。

枚举前半段作为nums[i],双指针指向后半段。

时间复杂度为\(O(n)\),空间复杂度为\(O(1)\)

class Solution:
    def maxNumOfMarkedIndices(self, nums: List[int]) -> int:
        nums.sort()  # O(nlogn)
        n = len(nums)
        ans = 0
        r = n//2
        for l in range(n//2):
            while r<n and  nums[r]<nums[l]*2  :r+=1
            if r>=n:break
            r+=1
            ans+=2
        return ans

需要说明的是,对于数组的长度\(n\),其结果最大为\(n//2*2\)
因此如果n为奇数,其n//2的位置也是不可能作为i的

posted @ 2024-09-12 22:23  TICSMC  阅读(15)  评论(0)    收藏  举报