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

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

2天前

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

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


原创内容 转载请注明出处

分享给朋友:

相关文章

【牛客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。题目难点在...

LeetCode 2523题解:寻找区间内最小间隔质数对(C++代码)

LeetCode 2523题解:寻找区间内最小间隔质数对(C++代码)

一、题目解读LeetCode 2523题要求在一个给定的整数区间 [left, right] 内,找到间隔最小的两个质数(即相邻质数的差值最小),并返回这对质数。若区间内不存在两个质数,则返回 [-1...

力扣LCR074题区间合并算法解析:贪心排序与区间重叠处理

力扣LCR074题区间合并算法解析:贪心排序与区间重叠处理

一、题目解读力扣LCR074题要求对给定的二维区间数组(每个区间由起始点和终止点构成)进行合并,将重叠的区间合并为更宽的区间,最终输出不重叠的合并结果。例如,输入[[1,3],[2,6],[8,10]...

力扣2588题解:利用前缀异或和与哈希表求解美丽子数组问题

力扣2588题解:利用前缀异或和与哈希表求解美丽子数组问题

一、题目解读力扣2588题要求计算给定数组中“美丽子数组”的数量。所谓“美丽子数组”,是指子数组的异或和为0。题目关键在于理解子数组异或和的性质,并通过高效算法统计符合条件的子数组数量。二、解题思路采...

发表评论

访客

看不清,换一张

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