
2026-01-06:使数组平衡的最少移除数目。用go语言,给定一个整数数组 nums 和一个整数 k。我们把满足“数组中最大值与最小值之比不超过 k”的非空数组称为平衡数组。你被允许从 nums 中去掉任意个元素(但不能把数组清空),要求找到使剩下元素构成平衡数组所需删除的最少元素个数。 注意:长度为 1 的数组自动视为平衡。
1 <= nums.length <= 100000。
1 <= nums[i] <= 1000000000。
1 <= k <= 100000。
输入:nums = [1,6,2,9], k = 3。
输出:2。
解释:
移除 nums[0] = 1 和 nums[3] = 9 得到 nums = [6, 2]。
现在 max = 6, min = 2,且 max <= min * k,因为 6 <= 2 * 3。因此,答案是 2。
题目来自力扣3634。
首先对输入数组进行升序排序。排序后数组元素从小到大排列,这样便于后续的滑动窗口操作。
对于示例 nums = [1, 6, 2, 9], 排序后变为 [1, 2, 6, 9]。
排序后,使用双指针技术维护一个滑动窗口:
窗口滑动过程如下:
i从数组开头遍历到结尾,每次移动一位nums[left] * k < nums[i](i - left + 1),并与之前记录的最大值比较更新平衡数组的条件是:最大值 ≤ 最小值 × k。
在排序后的数组中,对于窗口[left, i]:
nums[left]是窗口中的最小值(因为数组已排序)nums[i]是窗口中的最大值(因为数组已排序)因此,平衡条件简化为:nums[i] ≤ nums[left] × k。
最终需要删除的最少元素数为:原数组长度 - 最长有效子数组长度。
在示例中,排序后数组为[1, 2, 6, 9],k=3:
[2, 6](长度=2)slices.Sort(),基于快速排序实现,平均时间复杂度为O(n log n),其中n是数组长度。这种解法巧妙地利用了排序后数组的特性,将原本需要检查所有子数组的O(n²)暴力解法优化为O(n log n)的高效算法。滑动窗口技术确保了我们能够在线性时间内找到最优解。
.
package main
import (
"fmt"
"slices"
)
func minRemoval(nums []int, k int)int {
slices.Sort(nums)
maxSave, left := 0, 0
for i, mx := range nums {
for nums[left]*k < mx {
left++
}
maxSave = max(maxSave, i-left+1)
}
returnlen(nums) - maxSave
}
func main() {
nums := []int{1, 6, 2, 9}
k := 3
result := minRemoval(nums, k)
fmt.Println(result)
}

.
# -*-coding:utf-8-*-
def min_removal(nums, k):
"""
找到最少需要移除的元素数量,使得剩余数组中任意两元素满足 nums[i] * k >= nums[j]
且 nums[i] <= nums[j]
参数:
nums: List[int] - 整数数组
k: int - 比例系数
返回:
int - 最少需要移除的元素数量
"""
nums.sort()
max_save = 0
left = 0
for i, mx in enumerate(nums):
# 移动左指针,直到满足条件
while nums[left] * k < mx:
left += 1
# 更新可以保留的最大元素数量
max_save = max(max_save, i - left + 1)
returnlen(nums) - max_save
def main():
nums = [1, 6, 2, 9]
k = 3
result = min_removal(nums, k)
print(result)
if __name__ == "__main__":
main()
.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int minRemoval(vector<int>& nums, int k) {
// 首先对数组进行排序
sort(nums.begin(), nums.end());
int maxSave = 0;
int left = 0;
// 使用滑动窗口找到可以保留的最大元素数
for (int i = 0; i < nums.size(); i++) {
// 移动左指针,直到满足条件
while (left < i && nums[left] * k < nums[i]) {
left++;
}
// 更新可以保留的最大元素数量
maxSave = max(maxSave, i - left + 1);
}
return nums.size() - maxSave;
}
int main() {
vector<int> nums = {1, 6, 2, 9};
int k = 3;
int result = minRemoval(nums, k);
cout << result << endl;
return0;
}

·
我们相信人工智能为普通人提供了一种“增强工具”,并致力于分享全方位的AI知识。在这里,您可以找到最新的AI科普文章、工具评测、提升效率的秘籍以及行业洞察。 欢迎关注“福大大架构师每日一题”,发消息可获得面试资料,让AI助力您的未来发展。
·