【问题标题】:Find the first duplicate number for which the second occurrence has the minimal index查找第二次出现具有最小索引的第一个重复数字
【发布时间】:2017-12-20 05:14:03
【问题描述】:

这是一个关于codefights的问题:

给定一个数组 a 只包含从 1 到 a.length,找到第二个重复的数字 出现具有最小索引。换句话说,如果有更多 超过 1 个重复的数字,返回第二个的数字 出现的索引小于另一个的第二次出现 数字可以。

我一直在努力弄清楚如何在 python 中完成这项工作。我不确定我是否走在正确的道路上,如果我在从我的 d 字典中找到特定值后,我似乎无法弄清楚如何访问我的索引字典。我想在我的 d 字典中获取所有大于 1 的值,然后从 index 中获取这些值,然后 index 中较小的值就是答案。

如果我完全错了,请告诉我。

def firstDuplicate(a):
    d = {}
    index = {}

    for i in a:
        if i in d:
            d[i] += 1
        else:
            d[i] = 1

    for i,e in enumerate(a):
        if e in d:
            index[e] = i
        else:
            index[e] = i

    for key,val in d.items():
        if val > 1:

【问题讨论】:

  • 你试过运行这段代码吗?

标签: python algorithm python-2.7 dictionary data-structures


【解决方案1】:

我认为您可以在这里尝试使用索引技术。由于您提到数字在 1 到 a.length 的范围内,您可以从列表中检索该元素,转到索引 l[i] 并将该元素更改为 -l[l[i]]

l[l[i]] = -1 * l[l[i]]

执行此操作时,如果遇到负值,则返回此索引处存在的元素的绝对值。如果您在执行此操作时遇到问题,请告诉我。下面是代码:(之前忘了提):

l = [7,4,5,6,4,2,3]
found = 0
for i in range (0 , 6):
    item = abs(l[i])
    if(l[item - 1] > 0):
        l[item - 1] = -1 * l[item - 1]
    else:
        found = abs(l[i])
        break    
print (found)


output : 4

时间复杂度:O(n)

空格:O(1)

【讨论】:

    【解决方案2】:

    您的第二个for 循环对ifelse 条件执行相同的操作,让我们更改for 循环,此外,不需要存储出现次数少于两次的元素,所以让我们添加条件也是。这里的第二个循环所做的是,使用列表推导,它将所有出现的元素存储在列表中(Famous solution),然后我们将其存储在 indexdic 中。最后,打印两个字典看看它们的样子:

    def firstDuplicate(a):
        d = {}
        indexdic = {}
    
        for element in a:
            if a.count(element) > 1:
                if element in d:
                    d[element] += 1
                else:
                    d[element] = 1
    
        for key in d:
            indexdic[key] = [i for i, x in enumerate(a) if x == key]
    
        print('d: ', d)
        print('indexdic: ', indexdic)
    

    运行这个:

    >>> firstDuplicate(['a','b','c','a','d','d','b'])
    d:  {'a': 2, 'd': 2, 'b': 2}
    indexdic:  {'a': [0, 3], 'd': [4, 5], 'b': [1, 6]}
    

    现在,在这个提示之后,您需要处理 indexdic 值中需要哪些操作才能获得您想要的输出,我会让您解决这个问题,毕竟这是一个练习。如果有任何步骤没有很好地描述,请告诉我。

    【讨论】:

      【解决方案3】:

      Emm...简单的方法有什么问题?

      def firstDuplicate(a):
      
         aset = set()
         for i in a:
             if i in aset:
                 return i
             else:   
                 aset.add(i)
      
      print(firstDuplicate([7,4,5,6,4,6,3]))  
      

      字典版本:

      adict = {}
      for i in a:
         if i in adict:
             return i
         else:   
             adict[i] = 1   
      

      【讨论】:

      • 呃,我不敢相信我没想到这一点。谢谢:)
      • 上述方案的时间和空间复杂度是多少?
      • @frp farhan 取决于集合/字典的实现。通常每个操作 O(1),所以总体上是 O(M),其中 M 是第一个副本的索引(在最坏的情况下是 O(N))
      • 不,我们必须在第一次重复之前检查所有条目。顺便说一句,这是个好时机。
      【解决方案4】:

      正如我在另一篇文章中提到的,关键是使用字典。这是python 3的解决方案。索引是数字,因此您之前是否看过它就会知道。

       def firstDuplicate(a):
          oldies={}
          notfound=True
          for i in range(len(a)):
              try:
                  if oldies[a[i]]==a[i]:
                      notfound=False
                      return a[i]     
              except:
                  oldies[a[i]]=a[i]
          if notfound:
              return -1    
      

      【讨论】:

        【解决方案5】:
        def firstDuplicate(a):
        lst = list()
        x=-1
        for i in a:
            if i in lst:
                x = i
                break
            else:
               lst.append(i)
        return(x)
        

        这个答案解决了 20/22 输入。 Codefights 给出超过时间限制的错误。

        【讨论】:

          【解决方案6】:

          为了更快的结果,我们需要使用集合而不是列表。

          def first_duplicate(arr):
                  uniques = set()
                  for item in arr:
                      if item in uniques:
                          return item
                      else:
                          uniques.add(item)
              
                  return -1
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-06-20
            • 1970-01-01
            • 2018-11-07
            • 1970-01-01
            • 1970-01-01
            • 2023-03-25
            相关资源
            最近更新 更多