求出最多标记下标
难度:
标签:
题目描述
You are given a 0-indexed integer array nums
.
Initially, all of the indices are unmarked. You are allowed to make this operation any number of times:
- Pick two different unmarked indices
i
andj
such that2 * nums[i] <= nums[j]
, then marki
andj
.
Return the maximum possible number of marked indices in nums
using the above operation any number of times.
Example 1:
Input: nums = [3,5,2,4] Output: 2 Explanation: In the first operation: pick i = 2 and j = 1, the operation is allowed because 2 * nums[2] <= nums[1]. Then mark index 2 and 1. It can be shown that there's no other valid operation so the answer is 2.
Example 2:
Input: nums = [9,2,5,4] Output: 4 Explanation: In the first operation: pick i = 3 and j = 0, the operation is allowed because 2 * nums[3] <= nums[0]. Then mark index 3 and 0. In the second operation: pick i = 1 and j = 2, the operation is allowed because 2 * nums[1] <= nums[2]. Then mark index 1 and 2. Since there is no other operation, the answer is 4.
Example 3:
Input: nums = [7,6,8] Output: 0 Explanation: There is no valid operation to do, so the answer is 0.
Constraints:
1 <= nums.length <= 105
1 <= nums[i] <= 109
代码结果
运行时间: 108 ms, 内存: 30.0 MB
// 思路:
// 1. 对数组进行排序。
// 2. 使用Java Stream生成一个包含所有有效对的流。
// 3. 对有效对的数量求和。
import java.util.Arrays;
import java.util.stream.IntStream;
public class Solution {
public int maxMarkedIndices(int[] nums) {
Arrays.sort(nums); // 对数组进行排序
boolean[] marked = new boolean[nums.length]; // 标记数组
return (int) IntStream.range(0, nums.length)
.filter(i -> !marked[i])
.flatMap(i -> IntStream.range(i + 1, nums.length)
.filter(j -> 2 * nums[i] <= nums[j] && !marked[j])
.peek(j -> {
marked[i] = true; // 标记i
marked[j] = true; // 标记j
}))
.count() * 2; // 返回结果
}
}
解释
方法:
此题解采用排序加贪心的方法来解决问题。首先对数组 nums 进行排序,这样更容易找到满足 2 * nums[i] <= nums[j] 的 i 和 j。由于数组已排序,对于较小的元素,我们需要寻找后半部分中首个满足条件的较大元素。算法从数组的中点开始向后遍历,尝试找到与前半部分的元素 i 形成合法对的元素 j。如果找到了,i 指针向前移动,表示我们标记了一对下标。由于每次操作标记两个下标,所以返回的是成功匹配的对数乘以 2。
时间复杂度:
O(n log n)
空间复杂度:
O(1)
代码细节讲解
🦆
为什么在解题中选择排序后再进行双指针遍历,直接遍历不可以吗?
▷🦆
在进行排序操作后,原始数组的下标顺序被改变,这对算法找到的下标对有什么影响?
▷🦆
算法中为什么从数组的中点开始遍历,直接从头到尾遍历不可以吗?
▷🦆
对于数组的每一个元素i,算法如何保证每次都能找到满足条件的最优j?
▷