Medium
题目描述
给定一个按非递减顺序排序的整数数组 nums。
你可以执行以下操作任意次:
- 选择两个下标
i和j,其中nums[i] < nums[j]。 - 然后,从
nums中移除下标i和j处的元素。剩余元素保持原有顺序,数组重新编号。
返回执行零次或多次操作后 nums 的最小长度。
示例 1:
输入:nums = [1,2,3,4]
输出:0
解释:可以移除所有元素对。
示例 2:
输入:nums = [1,1,2,2,3,3]
输出:0
解释:可以移除所有元素对。
示例 3:
输入:nums = [1000000000,1000000000]
输出:2
解释:由于两个数字相等,无法移除。
示例 4:
输入:nums = [2,3,4,4,4]
输出:1
解释:可以移除4对元素,剩余1个。
约束条件:
1 <= nums.length <= 10^51 <= nums[i] <= 10^9nums按非递减顺序排序
解题思路
解题思路
这是一个贪心问题,关键在于如何最大化移除的元素对数。
基本观察: 要最大化移除操作次数,应该选择最小的k个元素和最大的k个元素进行配对。因为:
- 小元素更容易与大元素形成有效配对(满足 nums[i] < nums[j])
- 这样的策略能够最大化可配对的数量
核心思路: 设我们要进行k次移除操作,那么:
- 选择最小的k个元素:nums[0], nums[1], …, nums[k-1]
- 选择最大的k个元素:nums[n-k], nums[n-k+1], …, nums[n-1]
- 将第i小的元素与第i大的元素配对
有效配对的条件: 对于每个i ∈ [0, k-1],必须满足 nums[i] < nums[n-k+i]
算法步骤:
- 使用二分查找找到最大的有效k值
- 答案为 n - 2*k(总长度减去移除的元素个数)
优化思路: 也可以直接统计出现次数最多的元素频率maxFreq,答案为max(0, 2*maxFreq - n)。这是因为当某个元素出现次数超过一半时,多余的部分无法配对移除。
代码实现
class Solution {
public:
int minLengthAfterRemovals(vector<int>& nums) {
int n = nums.size();
int left = 0, right = n / 2;
while (left < right) {
int mid = left + (right - left + 1) / 2;
if (nums[mid - 1] < nums[n - mid]) {
left = mid;
} else {
right = mid - 1;
}
}
return n - 2 * left;
}
};
class Solution:
def minLengthAfterRemovals(self, nums: List[int]) -> int:
n = len(nums)
left, right = 0, n // 2
while left < right:
mid = left + (right - left + 1) // 2
if nums[mid - 1] < nums[n - mid]:
left = mid
else:
right = mid - 1
return n - 2 * left
public class Solution {
public int MinLengthAfterRemovals(IList<int> nums) {
int n = nums.Count;
int left = 0, right = n / 2;
while (left < right) {
int mid = left + (right - left + 1) / 2;
if (nums[mid - 1] < nums[n - mid]) {
left = mid;
} else {
right = mid - 1;
}
}
return n - 2 * left;
}
}
var minLengthAfterRemovals = function(nums) {
const n = nums.length;
let left = 0, right = Math.floor(n / 2);
while (left < right) {
const mid = left + Math.floor((right - left + 1) / 2);
if (nums[mid - 1] < nums[n - mid]) {
left = mid;
} else {
right = mid - 1;
}
}
return n - 2 * left;
};
复杂度分析
| 复杂度类型 | 大小 |
|---|---|
| 时间复杂度 | O(log n) |
| 空间复杂度 | O(1) |