当前位置:首页 > 力扣 > LeetCode 2576题解:双指针法求解最多标记下标(排序+贪心策略)

LeetCode 2576题解:双指针法求解最多标记下标(排序+贪心策略)

11小时前

LeetCode 2576题解:双指针法求解最多标记下标(排序+贪心策略) 双指针 贪心策略 力扣题解 指针 第1张

一、题目解读

LeetCode 2576题要求在一个整数数组中寻找最多可标记的下标对:若 nums[i] * 2 <= nums[j](i ≠ j),则下标 i 和 j 可配对标记。例如,输入 [3,1,2,4,5],可标记 (0,3) 和 (2,4),输出最多标记对数为 2。题目难点在于如何在无序数组中高效找到符合条件的配对,并最大化配对数量。

二、解题思路

采用“排序+双指针法+贪心策略”的组合思路:

1. 排序预处理:对原数组 nums 进行升序排序,确保相同元素聚集,便于后续配对。

2. 双指针划分:将排序后的数组分为左右两半(左指针 left=0,右指针 right=n/2),从中间向两端扩展寻找配对。

3. 贪心匹配:若 2 * nums[left] <= nums[right],则 left 与 right 可配对,同时双指针向内收缩(left++, right++);否则仅右指针右移,寻找更大 nums[right]。

4. 计数优化:每次配对成功计数加2,最终返回总配对数。

三、解题步骤

1. 排序数组:调用 sort(nums.begin(), nums.end()) 将 nums 升序排列。

2. 初始化指针:

○ left=0(左半区起始),right=n/2(右半区起始)。

3. 循环匹配,当 left < n/2 且 right < n 时:

    若 2 * nums[left] <= nums[right],说明 left 与 right 可配对,计数 count += 2,双指针向内移动(left++, right++)。

    否则(nums[left] * 2 > nums[right]),仅右指针右移(right++),尝试更大数值配对。

4. 返回结果:最终 count 即为最多可标记的下标对数。

四、代码及注释

class Solution {
public:
    int maxNumOfMarkedIndices(vector<int>& nums) {
        sort(nums.begin(), nums.end());  // 先对数组排序,便于后续双指针匹配
        int n = nums.size();
        int left = 0, right = n / 2;     // 左右指针初始化(左从0开始,右从中间开始)
        int count = 0;                   // 标记对数量
        while (left < n / 2 && right < n) {  // 循环条件:左右指针均未越界
            if (2 * nums[left] <= nums[right]) {  // 若满足配对条件
                count += 2;                   // 计数+2,标记一对
                left++;                       // 左指针右移(寻找下一可配对元素)
                right++;                     // 右指针右移(因排序后右半区递增,需尝试更大值)
            } else {                          // 若不满足条件
                right++;                     // 仅右指针右移,跳过当前left与right的组合
            }
        }
        return count;                      // 返回最终标记对数
    }
};

五、总结

本解法通过排序将无序问题转化为有序区间配对,结合双指针法实现高效贪心匹配,时间复杂度为 O(nlogn)(排序)+ O(n)(双指针遍历),空间复杂度为 O(1)(原地排序)。关键点包括:

1. 排序预处理:确保元素有序,降低后续匹配复杂度。

2. 双指针贪心策略:通过固定左指针、移动右指针寻找配对,避免暴力枚举

3. 边界判断优化:利用排序后的递增特性,不满足条件时直接右移指针,减少无效比较。

算法兼顾效率与简洁性,是解决此类区间匹配问题的典型优化思路,适用于需要最大化配对数的场景。


原创内容 转载请注明出处

分享给朋友:

相关文章

力扣5:中心扩散法 轻松破解最长回文子串

力扣5:中心扩散法 轻松破解最长回文子串

题目解读:在一个给定的字符串中,我们需要找到最长的回文子串。回文是指正读反读都相同的字符串,如"aba"、"abba"都是回文。这个问题看似简单,但要在字符串中...

力扣144:递归之美 轻松掌握二叉树前序遍历

力扣144:递归之美 轻松掌握二叉树前序遍历

题目解读二叉树的前序遍历是一种基础但重要的树遍历方式,其遍历顺序为:先访问根节点,然后递归地前序遍历左子树,最后递归地前序遍历右子树。给定一个二叉树的根节点,我们需要按照这个顺序访问所有节点,并将它们...

【力扣2846题】图论+二进制提升:高效解决连通性问题(附C++代码)

【力扣2846题】图论+二进制提升:高效解决连通性问题(附C++代码)

一、题目解读力扣2846题要求解决一个基于图连通性的操作优化问题。给定一个无向图,包含边权重,以及一系列查询,每个查询询问两点间路径的最小操作次数。题目关键在于高效计算路径上权重分布的统计信息,并转化...

【牛客157题】:反转链表指定区间(虚拟头节点解法)

【牛客157题】:反转链表指定区间(虚拟头节点解法)

一、题目解读牛客第157题要求反转链表中第m到n个节点(包含m和n)的区间,并保持其他节点顺序不变。例如,给定链表1→2→3→4→5,m=2,n=4,应返回1→4→3→2→5。题目重点在于处理边界条件...

LeetCode 2778题解:平方和的高效计算与因数遍历优化(C++实现)

LeetCode 2778题解:平方和的高效计算与因数遍历优化(C++实现)

一、题目解读LeetCode 2778题要求计算数组中下标为n的因数的元素的平方和。例如,若n=6,其因数为1、2、3、6,则需计算nums[0]、nums[1]、nums[2]、nums[5]的平方...

力扣面试题02.05链表相加:虚拟头节点+迭代解法的详细解析

力扣面试题02.05链表相加:虚拟头节点+迭代解法的详细解析

一、题目解读力扣面试题02.05要求将两个链表表示的整数相加,每个节点存储一位数字(逆序),结果同样以链表形式返回。例如,链表1为7→2→4,链表2为5→6→3,相加结果应为2→9→8→7。题目难点在...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。