【问题标题】:Efficiently find number of pairs of duplicates有效地找到重复对的数量
【发布时间】:2017-06-19 01:36:19
【问题描述】:

我正在尝试找到一种算法,该算法可以返回列表中重复项对的数量。

示例: 输入:[13,4,8,4,13,7,13,9,13] 输出:7 (4 个 13 出现 6 对,两个 4 出现 1 对)

我的算法可以变得更高效吗?我希望它比 Theta(n^2) 更快

这是我所拥有的:

my_List=[13,3,8,3,13,7,13,9,13]

pairs=0
alreadySeen=[]

for element in my_List:
  howMany=0
  if element in alreadySeen:
    False
   else:
    howMany=my_List.count(element)
    pairs=pairs+((howMany*(howMany-1))/2)
    howMany=0
    alreadySeen.append(element)

print(pairs)

【问题讨论】:

  • 怎么能4 13's comes out to 6 pairs,为什么不能2 pairs
  • 我不知道python,我可以写这个是java/php/js/perl/c/c++
  • 4 个 13 将组成 6 个不同的独特对。 (13.1,13.2) (13.1,13.3) (13.1,13.4) (13.2, 13.3) (13.2, 13.4) (13.3, 13.4)
  • 伪代码也很好,我正在寻找它的效率。
  • 我想到了两个选项: 1. 使用 while 循环而不是迭代元素,然后在计算完已经看到的元素后删除它们,这样您就可以在较小的列表上进行操作。 2. 对列表进行排序,然后只计算连续的。找到一个简单的方程,例如从 4 个相同的数字到产生 6 对。

标签: python algorithm performance iteration big-o


【解决方案1】:

这是一个运行时间为 O(N) 的算法。

  1. 遍历元素一次以创建每个元素及其计数的字典。 对于您的示例,此步骤的输出是 {13: 4, 4:2, 8:1, ...}
  2. 迭代该字典并计算每个元素的对数。每个元素的对数可以认为是从 N 个元素的列表中选择 2 个项目。这可以通过使用公式 (N * (N-1)) / 2 计算 combinations 来完成。因此,对于 4 个元素,有 (4 * 3) / 2 = 6 对。

【讨论】:

  • 为什么不是 O(N^2) ?你说要为 dict 遍历所有元素,然后再为计算遍历所有元素?
  • @JamalCrawford.. 做某事两次会导致 O(2N),这只是 O(N),因为常量值在大 O 表示法中被忽略:stackoverflow.com/questions/22188851/…
【解决方案2】:

@Hesham Attia 已经提供了正确的算法,这里是 Counter 的简单实现:

>>> from collections import Counter
>>> l = [13,4,8,4,13,7,13,9,13]
>>> sum(x * (x - 1) // 2 for x in Counter(l).values())
7

【讨论】:

    【解决方案3】:

    这是一段javascript代码,你可以把它转换成phython代码,复杂度是线性的~O(n)

    var arr = [13,3,8,3,13,7,13,9,13];
    var count = {};
    var totalpairs =0;
    for(var i=0;i<arr.length;i++){
      if(count[arr[i]]){
        count[arr[i]]++;
      }else{
        count[arr[i]] =1;
      }
    }
    
    for(key in count){
      if(count[key] %2 == 0){
        totalpairs = totalpairs + count[key]/2;
      }
    }
    
    console.log(' total pairs are '+ totalpairs);
    

    【讨论】:

      【解决方案4】:

      这是一种在时间复杂度约为 O(N) 的列表中查找所有可能重复对的简单而有效的方法。

      l = [13,3,8,3,13,7,13,9,13]
      # Two pairs of 13 and One pair of 3
      # Sum equals to Three
      alreadySeen = []
      total_no_of_pairs = 0
      for i in range(len(l)):
          if l[i] not in alreadySeen:
              alreadySeen.append(l[i])
          else:
              # If element l[i] is present in alreadySeen list
              # Indicates a Pair and increments count
              # Remove element for creating a new pair
              total_no_of_pairs +=1
              alreadySeen.remove(l[i])
      
      print(total_no_of_pairs)
      

      输出:

      3
      

      【讨论】:

        【解决方案5】:

        时间复杂度:O(N)

        arr = list(map(int,input().split()))
            d = {}
            for i in range(len(arr)):
                if arr[i] in d.keys():
                    d[arr[i]] += 1
                else:
                    d[arr[i]] = 1
            ans = 0
            for val in d.values():
                if val > 1:
                    ans += val*(val-1)//2
            print(ans)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-11-17
          • 1970-01-01
          • 1970-01-01
          • 2018-12-25
          • 2019-03-22
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多