一、代码与执行结果

财经新闻是大众了解金融事件的重要渠道,现有N位编辑,分别对K篇新闻进行专业的编辑与排版。需要您找出被这N位编辑共同编辑过的新闻,并根据这些新闻ID升序排列返回一个数组。

算法-找出N个数组的共同元素_时间复杂度

import random

# 查找编辑共同处理的新闻id
def find_common_news(N, K, news_ids):
    # 使用集合的交集操作找出被所有编辑共同编辑过的新闻
    common_news_set = set(news_ids[0]) # 时间 O(k)   # 空间 O(N)
    for i in range(1, N):  # O(N*K)
        common_news_set.intersection_update(news_ids[i]) 
    # 返回升序排列的结果
    return sorted(list(common_news_set)) # O(M * log(M)) 排序算法是 Timsort
    #  O(N * K + M * log(M))

# 生成模拟数据, 作为find_common_news的输入
def generate_random_lists(m=8, N=10, K=60):
    # 第1步:生成这些编辑们处理的新闻中一定重复的新闻id
    lists = random.sample(range(1, K+1), m)
    print('期望输出: ',sorted(lists)) 
    
    # 第2步:生成编辑们分别处理的新闻个数
    lsts2 = [random.randint(1, K) for _ in range(N)]
    # print(lsts2)

    # 第3步:生成这8个编辑各自处理的新闻中可能不重复的新闻id
    result = []
    for num in lsts2:
        rand_nums = [random.randint(1, K) for _ in range(num)]
        result.append(rand_nums)
    # print(result) 

    # 第4步:将可能不重复部分列表与重复列表合并, 得到每个编辑处理的新闻id列表模拟数据
    merged_result = []
    for sublist in result:
        # 注意:可能不重复部分列表 
        merged_list = list(set(sublist + lists))
        random.shuffle(merged_list) # 防止自动排序, 打乱处理
        merged_result.append(merged_list)
    return merged_result # 输出10个编辑分别处理的新闻id


if __name__ == "__main__":
    # 构造数据
    m, N, K = 8, 10, 60 # m为编辑们共同处理的新闻个数
    merged_result = generate_random_lists(m, N, K) # 生成编辑们各自处理的新闻id列表
    print('输入: ', merged_result)
    print("实际输出: ",find_common_news(N, K, merged_result))

输出:

期望输出:  [3, 16, 17, 22, 31, 32, 34, 52]
输入:  [[3, 40, 34, 22, 52, 14, 35, 31, 27, 32, 16, 17], [32, 8, 9, 3, 52, 36, 33, 44, 60, 12, 19, 17, 34, 43, 2, 10, 50, 45, 14, 42, 22, 41, 51, 55, 27, 11, 16, 39, 35, 15, 59, 49, 47, 28, 1, 26, 4, 31], [17, 33, 12, 24, 52, 47, 32, 23, 58, 27, 1, 16, 31, 18, 42, 60, 28, 19, 15, 3, 20, 53, 49, 57, 25, 21, 26, 9, 56, 35, 14, 4, 22, 5, 10, 13, 34, 8, 41], [40, 51, 21, 36, 34, 10, 52, 31, 57, 26, 41, 3, 32, 12, 9, 56, 39, 7, 59, 13, 17, 53, 22, 4, 27, 42, 16, 25], [35, 31, 27, 22, 39, 40, 11, 58, 30, 16, 56, 47, 17, 26, 34, 12, 53, 5, 3, 45, 1, 8, 32, 18, 52, 6], [9, 40, 26, 36, 39, 35, 54, 34, 17, 46, 43, 13, 52, 56, 37, 14, 45, 22, 6, 41, 25, 49, 20, 5, 7, 3, 31, 44, 50, 4, 30, 32, 16, 1], [2, 33, 32, 3, 8, 43, 31, 58, 42, 17, 1, 16, 52, 30, 59, 6, 34, 13, 29, 46, 51, 12, 22], [57, 31, 16, 14, 32, 9, 20, 18, 24, 30, 4, 17, 22, 27, 43, 12, 37, 2, 13, 59, 34, 53, 3, 48, 21, 55, 52, 25], [24, 3, 34, 31, 56, 19, 12, 8, 16, 52, 51, 10, 22, 32, 49, 33, 17, 2, 48, 15, 45, 42, 25, 60, 30, 46, 47, 36, 39, 58, 6, 20, 5, 37, 14], [17, 22, 58, 32, 52, 13, 5, 26, 34, 48, 3, 31, 27, 24, 2, 16]]
实际输出:  [3, 16, 17, 22, 31, 32, 34, 52]

二、函数关键信息

函数名称:find_common_news
参数N: 整数,表示编辑的数量。
参数K: 整数,表示新闻的总数。
news_ids: 一个包含N个列表的列表,每个列表包含一个编辑编辑过的新闻编号。
返回值:一个升序排列的列表,包含所有编辑共同编辑过的新闻编号。

三、程序设计原理

1、初始化一个空集合common_news_set,用于存储所有编辑共同编辑过的新闻编号。
2、将第一个编辑编辑过的新闻编号集合作为初始集合,存储到common_news_set中。
3、遍历第2到第N个编辑的新闻编号集合:
3.1、使用集合的intersection_update方法,将当前编辑的新闻编号集合与common_news_set取交集,并更新common_news_set。
3.2、这样,common_news_set中将保留与当前编辑共同编辑过的新闻编号,即找到所有编辑共同编辑过的新闻编号的交集。
4、将common_news_set转换为列表,并使用Python的sorted函数对列表进行升序排序。
5、返回排序后的列表作为结果。

四、复杂度分析

1、时间复杂度分析
1.1、使用集合的交集操作找出被所有编辑共同编辑过的新闻:遍历每个新闻集合进行交集操作,时间复杂度为O(K),其中K为所有编辑操作的总数。
1.2、排序:对交集结果进行排序,时间复杂度为O(NlogN),其中N为符合条件的新闻数量。
1.3、综合来看,时间复杂度为O(K + NlogN)。
2、空间复杂度分析
common_news_set集合:存储被所有编辑共同编辑过的新闻,最坏情况下需要存储所有新闻,空间复杂度为O(N)。