【问题标题】:Python / smallest positive integerPython / 最小正整数
【发布时间】:2020-06-20 08:51:13
【问题描述】:

我参加了以下代码演示任务 写一个函数:

定义解(A)

给定一个包含 N 个整数的数组 A,返回在 A 中没有出现的最小正整数(大于 0)。

例如,给定 A = [1, 3, 6, 4, 1, 2],函数应该返回 5。

给定 A = [1, 2, 3],函数应该返回 4。

给定 A = [−1, −3],函数应该返回 1。

为以下假设编写一个有效的算法:

N 是 [1..100,000] 范围内的整数; 数组 A 的每个元素都是 [−1,000,000..1,000,000] 范围内的整数。

我的解决方案

def solution(A):
    # write your code in Python 3.6
    l = len(A)
    B = []
    result = 0
    n = 0
    for i in range(l):
        if A[i] >=1:
            B.append(A[i]) 
    if B ==[]:
        return(1)
    else:    
       B.sort() 
       B = list(dict.fromkeys(B))
       n = len(B)
       for j in range(n-1):
           if B[j+1]>B[j]+1:
                result = (B[j]+1)
       if result != 0:
            return(result)
       else:
            return(B[n-1]+1)

虽然我尝试的所有输入都得到了正确的输出,但我的分数只有 22%。有人可以强调我哪里出错了。

【问题讨论】:

  • "我的分数只有 22%" 你能解释一下你的意思吗?是否存在导致错误结果的自动化测试?您能否提供失败案例的输入、预期输出和实际输出?

标签: python python-3.x


【解决方案1】:

时间复杂度 O(N) 空间复杂度 O(N) 的 Python 解决方案:

def solution(A):
    arr = [0] * 1000001
    for a in A:
        if a>0:
            arr[a] = 1
    for i in range(1, 1000000+1):
        if arr[i] == 0:
            return i

我的主要想法是:

  1. 为所有积极的可能性创建一个零初始化的“桶”。
  2. 迭代 A。每当遇到一个正数时,将它的存储桶标记为已访问 (1)。
  3. 遍历“桶”并返回第一个零“桶”。

【讨论】:

    【解决方案2】:
    # you can write to stdout for debugging purposes, e.g.
    # print("this is a debug message")
    def solution(A):
        # write your code in Python 3.6
        i = 1;
        B = set(A);
        while True:
            if i not in B:
                return i;
            i+=1;
    

    【讨论】:

    • 得分:100%。通过所有测试用例。
    【解决方案3】:

    我的 Javascript 解决方案。解决方法是对数组进行排序,比较数组的相邻元素。复杂度为 O(N)

    function solution(A) {
    // write your code in JavaScript (Node.js 8.9.4)
      A.sort((a, b) => a - b);
    
      if (A[0] > 1 || A[A.length - 1] < 0 || A.length <= 2) return 1;
    
      for (let i = 1; i < A.length - 1; ++i) {
        if (A[i] > 0 && (A[i + 1] - A[i]) > 1) {
            return A[i] + 1;
        }
      }
    
      return A[A.length - 1] + 1;
    }
    

    【讨论】:

      【解决方案4】:

      定义解决方案(A):

      s = set(A)
      for x in range(1,100002):
          if x not in s:
              return x
      pass
      

      并且获得了 100%

      【讨论】:

      • 已确认,不错!
      【解决方案5】:

      在 Codility 中,您必须正确预测其他输入,不仅是样本输入,而且还要获得良好的性能。我是这样做的:

      from collections import Counter
      def maior_menos_zero(A):
          if A < 0:
              return 1
      
          else:
              return 1 if A != 1 else 2
      
      def solution(A):
          if len(A) > 1:
              copia = set(A.copy())
              b = max(A)
              c = Counter(A)
              if len(c) == 1:
                  return maior_menos_zero(A[0])
      
              elif 1 not in copia:
                  return 1
      
              else:
                  for x in range(1,b+2):
                      if x not in copia:
                          return x
          else:
              return maior_menos_zero(A[0])
      

      100% 明白了。如果是 len(A) == 1 的数组 A,则将调用函数 maior_menos_zero。此外,如果它是一个len(A) > 1,但它的元素是相同的(Counter),那么函数maior_menos_zero将被调用再次。最后,如果1不在数组中,则1是其中最小的正整数,否则1在其中,我们将为 X in range(1,max(A)+2) 做一个 并检查它的元素是否在 A,此外,为了节省时间,X不在A中的第一次出现是最小的正整数

      【讨论】:

        【解决方案6】:

        我的解决方案(100% 接受):

        def solution(nums):
        
            nums_set = set()
            for el in nums:
                if el > 0 and el not in nums_set:
                    nums_set.add(el)
        
            sorted_set = sorted(nums_set)
        
            if len(sorted_set) == 0:
                return 1
        
            if sorted_set[0] != 1:
                return 1
        
            for i in range(0, len(sorted_set) - 1, 1):
                diff = sorted_set[i + 1] - sorted_set[i]
                if diff >= 2:
                    return sorted_set[i] + 1
        
            return sorted_set[-1] + 1
        

        【讨论】:

          【解决方案7】:

          试试这个,我假设列表未排序,但如果已排序,您可以删除 number_list = sorted(number_list) 以使其更快一点。

          def get_smallest_positive_integer(number_list):
              if all(number < 0 for number in number_list) or 1 not in number_list:
                  #checks if numbers in list are all negative integers or if 1 is not in list
                  return 1
              else:
                  try:
                      #get the smallest number in missing integers
                      number_list = sorted(number_list) # remove if list is already sorted by default
                      return min(x for x in range(number_list[0], number_list[-1] + 1) if x not in number_list and x != 0)
                  except:
                      #if there is no missing number in list get largest number + 1
                      return max(number_list) + 1
          
          
          print(get_smallest_positive_integer(number_list))
          

          输入:

          number_list = [1,2,3]
          

          输出:

          >>4
          

          输入:

          number_list = [-1,-2,-3]
          

          输出:

          >>1
          

          输入:

          number_list = [2]
          

          输出:

          >>1
          

          输入:

          number_list = [12,1,23,3,4,5,61,7,8,9,11]
          

          输出:

          >>2
          

          输入:

          number_list = [-1,3,2,1]
          

          输出:

          >>4
          

          【讨论】:

            【解决方案8】:

            我认为这应该像从 1 开始并检查哪个数字第一个没有出现一样简单。

            def solution(A):
                i = 1
                while i in A:
                    i += 1
            
                return i
            

            您也可以考虑将 A 的元素放入一个集合中(以获得更好的搜索性能),但我不确定这种情况是否值得。

            更新: 我一直在用 OP 给出的数字(从负百万到正百万和 100000 个元素的数字)进行一些测试。

            100000 elements:
            Linear Search: 0.003s
            Set Search: 0.017s
            
            1000000 elements (extra test):
            Linear Search: 0.8s
            Set Search: 2.58s
            

            【讨论】:

            猜你喜欢
            • 2021-04-01
            • 2011-02-07
            • 1970-01-01
            • 2022-01-20
            • 2016-01-19
            • 2020-12-07
            • 2017-01-21
            • 2013-02-10
            • 2012-06-13
            相关资源
            最近更新 更多