2576.求出最多标记下标

【LetMeFly】2576.求出最多标记下标:排序+双指针

力扣题目链接:https://leetcode.cn/problems/find-the-maximum-number-of-marked-indices/

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

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

  • 选择两个 互不相同且未标记 的下标 i 和 j ,满足 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 <= 105
  • 1 <= nums[i] <= 109

解题方法:排序+双指针

最多能凑够$\lfloor \frac{len(nums)}{2}\rfloor$对,因此可以先对原始数组排个序,$r$指针从下标$\lfloor \frac{len(nums)+1}{2}\rfloor$的元素开始向后遍历,$l$指针默认指向下标$0$。

如果$nums[l] \times 2\leq nums[r]$,则把$nums[l]$和$nums[r]$配成一对($ans+=2,l++,r++$);否则,$l$不变$r++$。

问: 为何不能从最小的元素开始二分查找大于等于它的二倍的第一个数?

答: 反例如下:[2, 4, 5, 9]。若24配成一对,则59不能再配对;而若25配对,则49还能配对。这也就是说为什么要从后半数组5开始找。

  • 时间复杂度$O(n\log n)$,其中$n=len(nums)$
  • 空间复杂度$O(\log n)$

时空复杂度主要来自排序。

AC代码

C++

1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution {
public:
int maxNumOfMarkedIndices(vector<int>& nums) {
sort(nums.begin(), nums.end());
int ans = 0;
for (int l = 0, r = (nums.size() + 1) / 2; r < nums.size(); r++) {
if (nums[l] * 2 <= nums[r]) {
ans += 2, l++;
}
}
return ans;
}
};

Go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package main
import "sort"

func maxNumOfMarkedIndices(nums []int) int {
sort.Ints(nums)
ans := 0
for l, r := 0, (len(nums) + 1) / 2; r < len(nums); r++ {
if nums[l] * 2 <= nums[r] {
ans += 2
l++
}
}
return ans
}

Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import java.util.Arrays;

class Solution {
public int maxNumOfMarkedIndices(int[] nums) {
Arrays.sort(nums);
int ans = 0;
for (int i = 0, r = (nums.length + 1) / 2; r < nums.length; r++) {
if (nums[i] * 2 <= nums[r]) {
ans += 2;
i++;
}
}
return ans;
}
}

Python

1
2
3
4
5
6
7
8
9
10
11
12
13
from typing import List

class Solution:
def maxNumOfMarkedIndices(self, nums: List[int]) -> int:
nums.sort()
ans = 0
l, r = 0, (len(nums) + 1) // 2
while r < len(nums):
if nums[l] * 2 <= nums[r]:
ans += 2
l += 1
r += 1
return ans

同步发文于CSDN和我的个人博客,原创不易,转载经作者同意后请附上原文链接哦~

Tisfy:https://letmefly.blog.csdn.net/article/details/142188013


2576.求出最多标记下标
https://blog.letmefly.xyz/2024/09/12/LeetCode 2576.求出最多标记下标/
作者
Tisfy
发布于
2024年9月12日
许可协议