【问题标题】:find common elements in two lists in linear time complexity以线性时间复杂度在两个列表中找到共同元素
【发布时间】:2021-05-07 11:49:27
【问题描述】:

我有两个没有重复的未排序整数列表,它们都包含相同的元素但顺序不同,我想以最低的时间复杂度找到两个列表之间公共元素的索引。例如

a = [1, 8, 5, 3, 4]
b = [5, 4, 1, 3, 8] 

输出应该是:

list1[0] With list2[2]
list1[1] With list2[4]
list1[2] With list2[0]
and so on 

我曾想过使用 set。交点,然后使用'index'函数找到索引,但我不知道如何以正确的方式打印输出

这是我尝试过的

b = set(list1).intersection(list2)
ina = [list1.index(x) for x in b]
inb = [list2.index(x) for x in b]
print (ina , inb )

【问题讨论】:

    标签: python list


    【解决方案1】:

    要在线性时间内找到它们,您应该使用某种散列。 Python 中最简单的方法是使用 dict:

    list1 = [1, 8, 5, 3, 4]
    list2 = [5, 4, 1, 3, 8]
    
    common = set(list1).intersection(list2)
    dict2 = {e: i for i, e in enumerate(list2) if e in common}
    result = [(i, dict2[e]) for i, e in enumerate(list1) if e in common]
    

    result 将是

    [(0, 2), (1, 4), (2, 0), (3, 3), (4, 1)]
    

    你可以用这样的东西来格式化和打印它:

    for i1, i2 in result:
        print(f"list1[{i1}] with list2[{i2}]")
    

    你得到:

    list1[0] with list2[2]
    list1[1] with list2[4]
    list1[2] with list2[0]
    list1[3] with list2[3]
    list1[4] with list2[1]
    

    【讨论】:

      【解决方案2】:

      创建一个字典,将一个列表的元素映射到它们的索引。然后更新它以获得另一个列表的相应元素的索引。那么任何有两个索引的元素都在交集中。

      intersect = {x: [i] for i, x in enumerate(list1)}
      for i, x in enumerate(list2):
          if x in intersect:
              intersect[x].append(i)
      for l in intersect.values():
          if len(l) == 2:
              print(f'list1[{l[0]}] with list2[{l[1]}]')
      

      【讨论】:

      • 我认为这不会以正确的顺序打印索引。
      • @Selcuk 我以为他只是想获取两个索引列表。我已经更新它以打印相应的索引。
      【解决方案3】:
      a = [1, 8, 5, 3, 4]
      b = [5, 4, 1, 3, 8]
      
      e2i = {e : i for (i, e) in enumerate(b)}
      for i, e in enumerate(a):
          if e in e2i:
              print('list1[%d] with list2[%d]' % (i, e2i[e]))
      

      【讨论】:

        【解决方案4】:

        在此处的出色答案的基础上,您无需费心记录a 的索引,就可以从柠檬中榨出更多汁液。 (无论如何,这些索引只是 0len(a) - 1,如果需要,您可以稍后添加它们。)

        e2i = {e : i for (i, e) in enumerate(b)}
        output = [e2i.get(e) for e in enumerate(a)]
        output
        # [2, 4, 0, 3, 1]
        

        在我的机器上使用len(a) == len(b) == 5000,这段代码的运行速度比 Björn Lindqvist 的代码快两倍(在我修改了他的代码以存储输出而不是打印它之后)。

        【讨论】:

          猜你喜欢
          • 2019-06-01
          • 2021-01-01
          • 2020-01-17
          • 1970-01-01
          • 1970-01-01
          • 2020-02-13
          • 1970-01-01
          • 2013-10-29
          • 1970-01-01
          相关资源
          最近更新 更多