📜  删除给定元素后找到k个最小的数字(1)

📅  最后修改于: 2023-12-03 15:22:44.051000             🧑  作者: Mango

删除给定元素后找到k个最小的数字

在数组中删除给定的一个或多个元素,然后找到k个最小的数字。这个问题可以通过排序和堆来解决。下面我们将介绍两种方法。

方法1: 排序

我们可以先删除给定的元素,然后对数组进行排序,最后找到前k个元素即可。

def k_smallest_after_deletion(arr, to_delete, k):
    # 删除给定元素
    for t in to_delete:
        arr[t] = "#"
    
    # 排序数组
    arr.sort()
    
    # 找到前k个最小元素
    return [x for x in arr if x != "#"][:k]

时间复杂度分析:

  • 删除元素的时间复杂度为O(m),其中m为要删除的元素的数量;
  • 排序的时间复杂度为O(nlogn),其中n为数组的长度;
  • 找到前k个元素的时间复杂度为O(k);
  • 因此,总时间复杂度为O(nlogn + k + m)。
方法2: 小根堆

另一种方法是使用小根堆。我们首先将数组中的元素插入到一个小根堆中,然后再依次删除给定元素,每次删除一个元素后,从堆中删除该元素,然后将堆中的前k个元素输出即可。

import heapq

def k_smallest_after_deletion(arr, to_delete, k):
    # 初始化小根堆
    heap = [(x, i) for i, x in enumerate(arr)]
    heapq.heapify(heap)
    
    # 从堆中删除给定元素
    for t in to_delete:
        while heap and heap[0][1] == t:
            heapq.heappop(heap)
    
    # 找到前k个最小元素
    return [heapq.heappop(heap)[0] for _ in range(k)]

时间复杂度分析:

  • 初始化堆的时间复杂度为O(n),其中n为数组的长度;
  • 删除元素的时间复杂度为O(mlogn),其中m为要删除的元素的数量;
  • 找到前k个元素的时间复杂度为O(klogn);
  • 因此,总时间复杂度为O(n + mlogn + klogn)。

综上所述,使用小根堆的方法具有更好的时间复杂度,特别是在k较小时更为明显。