(nice!!!)LeetCode 2576. 求出最多标记下标(二分查找、双指针)

题目:2576. 求出最多标记下标

在这里插入图片描述
在这里插入图片描述
方法一:二分查找。假设可以标记k对下标,那么也可以标记数量小于k对的下标。当最大标记的数量为k对时,那么大于k对的数量是不可能的。这就有一个单调性,可以采用二分查找。时间复杂度为0(nlogn),细节看注释。

class Solution {
public:
    bool check(int k,vector<int>& nums){
        int n=nums.size();
        //k:最多可以标记k对下标,那么用最小的k个数去配对k个最大的数即可
        for(int i=0;i<k;i++){
        	//如果有一个不满足,说明配对不了k对
            if(nums[i]*2>nums[n-k+i]) return false;
        }
        return true;
    }
    int maxNumOfMarkedIndices(vector<int>& nums) {
        int n=nums.size();
        //先将数组升序排序
        sort(nums.begin(),nums.end());
        //采用二分法进行查找,看可以配对多少对下标
        int l=0,r=n/2;
        while(l<r){
            int mid=(l+r+1)/2;
            if(check(mid,nums)) l=mid;
            else r=mid-1;
        }
        return l*2;
    }
};

方法二:双指针。最多可以配对k=n/2对下标,那么我们直接用最小的k个数来配对k个最大的数。时间复杂度为0(nlogn),细节看注释。

class Solution {
public:
    int maxNumOfMarkedIndices(vector<int>& nums) {
        int n=nums.size();
        sort(nums.begin(),nums.end());
        //i用来枚举最小的k个数,j用来枚举最大的k个数。
        int i=0,j=(n+1)/2;
        for(;j<n;j++){
        	//当前第i个数可以配对成功,那就继续看下一个数
            if(nums[i]*2<=nums[j]) i++;
        }
        return i*2;
    }
};
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值