首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >2026-01-06:使数组平衡的最少移除数目。用go语言,给定一个整数数组 nums 和一个整数 k。我们把满足“数组中最大值与最小值之比不超过 k

2026-01-06:使数组平衡的最少移除数目。用go语言,给定一个整数数组 nums 和一个整数 k。我们把满足“数组中最大值与最小值之比不超过 k

作者头像
福大大架构师每日一题
发布2026-01-12 11:09:59
发布2026-01-12 11:09:59
970
举报

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。

详细解决步骤

1. 数组排序

首先对输入数组进行升序排序。排序后数组元素从小到大排列,这样便于后续的滑动窗口操作。

对于示例 nums = [1, 6, 2, 9], 排序后变为 [1, 2, 6, 9]

2. 滑动窗口寻找最长有效子数组

排序后,使用双指针技术维护一个滑动窗口:

  • 左指针(left):表示当前考虑的子数组的起始位置
  • 右指针(i):表示当前考虑的子数组的结束位置

窗口滑动过程如下:

  1. 1. 外层循环:右指针i从数组开头遍历到结尾,每次移动一位
  2. 2. 内层循环:对于每个右指针位置,检查当前窗口是否满足平衡条件
    • • 条件判断:nums[left] * k < nums[i]
    • • 如果不满足(即窗口最大值与最小值之比超过k),则左指针向右移动,缩小窗口
  3. 3. 更新最大保留长度:对于每个有效的窗口,计算当前窗口长度(i - left + 1),并与之前记录的最大值比较更新

3. 核心平衡条件理解

平衡数组的条件是:最大值 ≤ 最小值 × k

在排序后的数组中,对于窗口[left, i]

  • nums[left]是窗口中的最小值(因为数组已排序)
  • nums[i]是窗口中的最大值(因为数组已排序)

因此,平衡条件简化为:nums[i] ≤ nums[left] × k

4. 计算需要删除的元素数量

最终需要删除的最少元素数为:原数组长度 - 最长有效子数组长度

在示例中,排序后数组为[1, 2, 6, 9],k=3:

  • • 最长有效子数组是[2, 6](长度=2)
  • • 需要删除的元素数 = 4 - 2 = 2

算法复杂度分析

时间复杂度

  • 排序操作:使用Go的slices.Sort(),基于快速排序实现,平均时间复杂度为O(n log n),其中n是数组长度。
  • 滑动窗口遍历:双指针各遍历数组一次,时间复杂度为O(n)
  • 总时间复杂度:由排序步骤主导,为O(n log n)

空间复杂度

  • 排序算法空间复杂度:Go的快速排序实现需要**O(log n)**的栈空间。
  • 其他变量:只使用了常数级别的额外空间(几个指针变量)。
  • 总空间复杂度O(log n)(主要由排序算法的递归调用栈引起)。

算法优势

这种解法巧妙地利用了排序后数组的特性,将原本需要检查所有子数组的O(n²)暴力解法优化为O(n log n)的高效算法。滑动窗口技术确保了我们能够在线性时间内找到最优解。

Go完整代码如下:

.

代码语言:javascript
复制
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)
}
在这里插入图片描述
在这里插入图片描述

Python完整代码如下:

.

代码语言:javascript
复制
# -*-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()
在这里插入图片描述
在这里插入图片描述

C++完整代码如下:

.

代码语言:javascript
复制
#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助力您的未来发展。

·

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-01-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 福大大架构师每日一题 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 详细解决步骤
    • 1. 数组排序
    • 2. 滑动窗口寻找最长有效子数组
    • 3. 核心平衡条件理解
    • 4. 计算需要删除的元素数量
  • 算法复杂度分析
    • 时间复杂度
    • 空间复杂度
  • 算法优势
  • Go完整代码如下:
  • Python完整代码如下:
  • C++完整代码如下:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档