滴滴前端编程笔试题 60min

众数

给你一个由正整数组成的集合,你需要从中删掉尽可能少的数使得该集合的众数出现次数不超过给定的参数k。最终你需要输出至少需要删除几个数。 第一行有两个正整数n,k(1<=k<=n<=100000),代表集合大小。

第二行有n个正整数,范围在1到1000000000之间,代表给出的集合。 输出一个非负整数,即至少需要从集合中删除几个数才能使得集合中众数的出现次数不超过k。

算法思路:

首先,我们需要找到该集合的众数,可以使用哈希表来实现。 接下来,我们需要计算众数在该集合中出现的次数,如果众数出现的次数小于等于k,则不需要删除任何数字,直接输出0即可。如果众数出现的次数大于k,则需要删除一些数字。我们可以将集合中的数字按照从小到大排序,然后遍历这些数字,如果当前数字与众数不同,则将计数器加1,表示需要删除该数字。如果当前数字与众数相同,则将计数器清零。在遍历过程中,记录下最小的计数器值,即为最少需要删除的数字个数。 时间复杂度:O(nlogn),其中n为集合大小。

参考代码:

from collections import defaultdict
n, k = map(int, input().split())
nums = list(map(int, input().split()))
# 找到集合中的众数
counter = defaultdict(int)
for num in nums:
    counter[num] += 1
mode = max(counter, key=counter.get)
# 计算众数出现的次数
mode_count = counter[mode]
# 如果众数出现的次数小于等于k,不需要删除任何数字
if mode_count <= k:
    print(0)
else:
    # 排序并遍历集合
    nums.sort()
    count = 0
    min_count = float("inf")
    for i in range(n):
        if nums[i] != mode:
            count += 1
        if count > k:
            count -= 1
            min_count = min(min_count, count)
        if nums[i] == mode:
            count = 0
    if min_count == float("inf"):
        min_count = n - k
    print(min_count)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值