当前位置: 首页 > article >正文

LeetCode: 2576. 求出最多标记的下标 排序+双指针,时间复杂度O(n*logn)

2576. 求出最多标记的下标

today 2576 求出最多标记的下标

题目描述

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

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

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

示例1:

输入:nums = [3,5,2,4]
输出:2
解释:第一次操作中,选择 i = 2 和 j = 1 ,操作可以执行的原因是 2 * nums[2] <= nums[1] ,标记下标 2 和 1 。
没有其他更多可执行的操作,所以答案为 2 。

示例2:

输入:nums = [9,2,5,4]
输出:4
解释:第一次操作中,选择 i = 3 和 j = 0 ,操作可以执行的原因是 2 * nums[3] <= nums[0] ,标记下标 3 和 0 。
第二次操作中,选择 i = 1 和 j = 2 ,操作可以执行的原因是 2 * nums[1] <= nums[2] ,标记下标 1 和 2 。
没有其他更多可执行的操作,所以答案为 4 。

示例3:

输入:nums = [7,6,8]
输出:0
解释:没有任何可以执行的操作,所以答案为 0 。

提示:

  • 1 <= nums.length <= 10^5
  • 1 <= nums[i] <= 10^9

题目解析

题目要求我们,找出数组中最多可以标记的下标数目。

我们需要成对找出满足 2 * nums[i] <= nums[j] 的数字。

也就是说,每一个较小的数,需要找到一个大的数来配对。我们首先可以对数组进行排序,然后使用双指针法来找出满足条件的数字对。设置左指针为left用于指向较小的数,右指针为right用于指向较大的数。我们很容易知道,较小的数,应该全部在nums数组的左半部分,较大的数应该全部在nums的右半部分。因此有0<=left<len(nums)/2-1, len(nums)/2<=right<len(nums)

初始化left=0用于标记数组中最小的数。初始化right=len(nums)/2用于标记数组中较大的数中最小的数。

  • 如果nums[left] * 2 <= nums[right],则我们可以标记leftright,并将left右移一位,right左移一位。

  • 如果nums[left] * 2 > nums[right],则我们需要将right右移一位。

直到leftright超出边界条件,我们就找到了所有满足条件的数字对。

复杂度分析:

  • 时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn)
  • 空间复杂度为 O ( 1 ) O(1) O(1)

代码实现

Python实现:

class Solution(object):
    def maxNumOfMarkedIndices(self, nums):
        n = len(nums)
        if n == 1:
            return 0
        nums.sort()
        ans = 0
        i, right = 0, n // 2
        
        # 双指针遍历
        while i < n // 2 and right < n:
            if nums[i] * 2 <= nums[right]:
                ans += 2
                i += 1
                right += 1
            else:
                right += 1
        
        return ans

Go实现:

func maxNumOfMarkedIndices(nums []int) int {
    n:=len(nums)
    if(n==1){
        return 0
    }
    ans:=0
    sort.Ints(nums) 
    left, right := 0, n/2
    for left<n/2 && right<n {
        if nums[left]*2<=nums[right]{
            left++
            right++
            ans+=2
        }else{
            right++
        }
    }
    return ans
}

C++实现:

class Solution {
public:
    int maxNumOfMarkedIndices(vector<int>& nums) {
        int n=nums.size();
        sort(nums.begin(),nums.end());
        int left=0,right=n/2;
        int ans=0;
        while(left<n/2&&right<n){
            if(nums[left]*2<=nums[right]){
                left++;
                right++;
                ans+=2;
            }else{
                right++;
            }
        }
        return ans;
    }
};

http://www.kler.cn/a/311235.html

相关文章:

  • Neo4j 和 Python 初学者指南:如何使用可选关系匹配优化 Cypher 查询
  • top-k类问题
  • uniapp发布到微信小程序,提示接口未配置在app.json文件中
  • 经典的ORACLE 11/12/19闪回操作
  • 使用Netty实现一个简单的聊天服务器
  • 每日OJ题_牛客_AB31活动安排_区间贪心_C++_Java
  • 基于224G的超高速以太网端口1.6Tbps 1600G真的来了~
  • 动手学习RAG: 迟交互模型colbert微调实践 bge-m3
  • 深度学习-物体检测SSD
  • 【60天备战2024年11月软考高级系统架构设计师——第21天:系统架构设计原则——高内聚低耦合】
  • mongodb 安装教程
  • 顺序表数据结构
  • TCP 和 UDP 协议的区别?
  • Open3D(C++) 点云中的植被信息提取
  • BPG的定义和工作原理是什么?
  • 定制相亲交友系统如何提升用户体验
  • SQL:子查询
  • Qwen 2.5:阿里巴巴集团的新一代大型语言模型
  • neo4j安装启动教程+对应的jdk配置
  • 巧用服务名解决主备集群中主库DMDSC节点间会话负载不均衡的问题
  • Activiti7《第二式:破剑式》——工作流中的以柔克刚
  • 算法:计算二叉树的最大深度(Java实现)
  • 翻页时钟 2.0-自动置顶显示,点击小时切换显示标题栏不显示标题栏-供大家学习研究参考
  • 【C++语言】模版的进一步学习
  • 网页打开时,下载的文件svg+xml类型有什么作用?
  • 99AutoML 自动化机器学习实践--NNI 自动化机器学习工具包