📌  相关文章
📜  门| Sudo GATE 2020 Mock III(2019年1月24日)|问题30(1)

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

介绍-门

在计算机科学中,"门"是一种用于在电子线路中转化输入信号为输出信号的基础电子元件。这些基本门电路可以组合形成更复杂的电子电路,从而完成各种计算和控制任务。

在计算机科学中,"门"通常用于描述逻辑电路。逻辑电路通常包括数字电路、电脑系统等,为了满足需求,我们需要将逻辑块组合成逻辑电路。

在数字逻辑中,我们主要使用两种基本元器件:逻辑门和触发器。其中逻辑门包括AND、OR、NOT等等,触发器包括D触发器、JK触发器等等。

门还可以用于描述控制逻辑和存储逻辑,这些通常用于设计电子电路、电脑系统、微控制器等等。

门 - Sudo GATE 2020 Mock III(2019年1月24日) - 问题30

在Sudo GATE 2020 Mock III(2019年1月24日)的问题30中,我们需要回答以下问题:

给定n个大小的非空集合S1, S2, ..., Sn, 假设每个集合Si是由小于10000的非负整数集合组成的,找到一个算法,以O(nlogn)的时间复杂度,返回至少出现在n/2个集合中的整数的数量。

我们可以先将每个集合中的数字进行排序,然后利用归并排序的思想,即先处理前两个集合,然后将结果与第三个集合比较,直到最后一个集合。在这个过程中,我们可以用树形数据结构存储中间结果,以减少比较和合并的时间。因为这个过程是逐级进行的,所以效率很高,它的时间复杂度为O(nlogn)。

代码

以下是Python代码实现:

import bisect

def merge_and_count(lst1, lst2): 
    i1, i2, l1, l2 = 0, 0, len(lst1), len(lst2)
    res = []
    inversions = 0
    while i1 < l1 and i2 < l2:
        if lst1[i1] <= lst2[i2]: 
            res.append(lst1[i1])
            i1 += 1
        else: 
            res.append(lst2[i2])
            i2 += 1
            inversions += l1 - i1
            
    res += lst1[i1:]
    res += lst2[i2:]
    return res, inversions
    
def merge_sort_with_count(lst): 
    if len(lst) == 1: 
        return lst, 0
    
    mid = len(lst) // 2
    left, a = merge_sort_with_count(lst[:mid])
    right, b = merge_sort_with_count(lst[mid:])
    res, c = merge_and_count(left, right)
    return res, a + b + c

def half_sets(lst): 
    n = len(lst)
    if n == 1: 
        return lst[0]
    mid = n // 2
    left = half_sets(lst[:mid])
    right = half_sets(lst[mid:])
    count = 0
    for l in left: 
        count += bisect.bisect_right(right, l) - bisect.bisect_left(right, l)
    return count

def num_of_repeated_numbers(n, lst_lst): 
    lst_lst = [merge_sort_with_count(e)[0] for e in lst_lst]
    return half_sets(lst_lst)

这个代码实现的整体思路是:

  1. 首先,我们将每个数字列表进行排序。
  2. 然后,我们将排序后的数字列表组合在一起,并使用归并排序的思想来找到至少出现在n/2个集合中的整数的数量。

这个算法的时间复杂度为O(nlogn)。