【问题标题】:Find the number from the set that is not present in the array从集合中找出数组中不存在的数字
【发布时间】:2020-03-09 00:38:30
【问题描述】:

我在一次采访中被问到这个问题:给你一组数字 {1..N} 和一个数组 A[N-1]。从集合中找出数组中不存在的数字。下面是我到目前为止的代码和伪代码,它不起作用。

我假设集合中有一个(并且只有一个)不在数组中的数字

  1. 遍历集合中的每个元素
  2. 遍历数组中的每个元素 O(n)
  3. 检查数字是否在数组中
  4. 如果是,什么也不做
  5. 否则,早点归还号码
def findMissingNo(arr, s):  
    for num in s: #loop through each element in the set
        for num2 in arr: ##loop through each element in the array O(n)
            if (num == num2): #if the number in the set is in the array, break 
                break
        print (num)
        return num #if the number in the set is not in the array, early return the number 
    return -1 #return -1 if there is no missing element 

s1 = {1,4,5}
arr1 = [1,4]

findMissingNo(arr1, s1)

【问题讨论】:

  • 你不能只做s1-set(arr1)吗?两组上的- 执行difference

标签: python arrays loops set


【解决方案1】:

根据定义,我们有一个从 1 到 N 的集合和一个大小为 N-1 的数组,其中包含从 1 到 N 的数字,缺少一个数字,我们必须找到那个数字

因为只有 1 个数字缺失,并且 set 有 n 个元素,而 array 有 n-1 个元素。所以数组是集合的子集,缺失元素为缺失,这意味着

all_number_of_set = all_number_of_array + missing_number

还有

sum_of_all_number_of_set = sum_of_array_number + missing_number

这意味着

missing_number = sum_of_all_number_of_set - sum_of_array_number

伪代码

def findMissingNo(set_, arr_ ):
      return sum(set_) - sum(arr_)

【讨论】:

  • 优雅,完全绕过了set和list的不同性质。我怀疑面试官想对此进行测试,但会对这个答案感到满意。
  • @KennyOstrom 我查看了问题的 OP 定义,是的,我想面试官正在寻找基本的数学知识、分析能力和代码优化 O(1)。
  • @KennyOstrom plus 正如 Op 提到的那样,集合包含一个来自 1..n 的数字并且数组的大小为 n-1,缺少集合中的 1 个数字,所以这种方法,(这是在面试题)
  • 我给了你+1,但我注意到这种方法非常依赖于行为良好的输入。如果你使用python内置的集差函数,你可以知道答案是0还是很多。
  • 谢谢,这种方法依赖于这样一个事实,一个集合有 N 个元素,而列表/数组有 n-1 个元素,没有重复。集合中的元素从 0 到 N 开始,在列表/数组中,它从 0 到 n,缺少 1 个元素。这是 OP 声明。我认为 OP 给出了一个错误的例子,或者没有提到完整的声明,this is the problem i guess
【解决方案2】:

如果我很好地理解了您的问题,那么您正在寻找找到set 号码的有效方法,该号码在list 中不存在。我看到你在内部循环,这将是O(n^2)。我建议将dict 设为list,即O(n),然后通过循环setO(n)dictionay 中找到O(1) 元素。考虑带有子集set 的大型list

def findMissingNo(arr_list, s_list):
    d = dict()
    for el in arr_list:
        d.update({el: el})
    for s in s_list:  
        try:
            d[s]
            pass
        except KeyError:
            return s
    return -1 

s1 = {1,4,5}
arr1 = [1,4]

findMissingNo(arr1, s1)

希望对你有帮助:)

【讨论】:

    【解决方案3】:

    您的函数是二次函数,因为它必须检查集合中每个项目的整个列表。

    不要对集合进行迭代,这一点很重要。是的,这可以工作,但是您表明您不知道可以从 python 中的集合或 dict(或一般的哈希表)中获得的时间复杂度优势。但是您也不能遍历列表,因为缺少的项目是......丢失。所以你不会在那里找到它。

    相反,您从列表中构建一个集合,并使用差异函数。或者更好的是,symmetric_difference (^) 见https://docs.python.org/3.8/library/stdtypes.html#set

    def findMissingNo(arr, s):        
        d = set(arr) ^ s # symmetric difference
        if 1 == len(d):
            for item in d:
                return item
    
    print (findMissingNo([1,4], {1,4,5}))
    

    5

    我采取了一些捷径,因为我知道我们想要一件物品,而且我知道它应该在哪个容器中。如果没有找到物品,我决定返回 None,但我没有检查多个物品。

    【讨论】:

      【解决方案4】:

      类似的东西呢:

      def findMissingNo(arr, s):
          for num in s:  # loop through each element in the set
              if num in arr:
                  pass
              else:
                  return num  # if the number in the set is not in the array, early return the number 
          return -1  # return -1 if there is no missing element 
      

      【讨论】:

      • 您可以通过删除 pass 来缩小它。
      • @KennyOstromcare 解释一下?首先,Python 中没有数组这样的东西。这是一个列表。其次,除了方法不同、没有顺序之外,集合基本上就是一个列表。
      • 在 O(1) 时间内找到集合(或字典键)的成员非常重要。我为我不屑一顾的语气道歉,但你的回答是错误的。
      • 感谢您的解释。我不认为我的回答是错误的(它完成了工作并且是朝着正确方向迈出的一步),但我同意它远不是最好的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-04-19
      • 1970-01-01
      • 2021-10-20
      • 1970-01-01
      • 2011-03-11
      • 2015-09-16
      • 1970-01-01
      相关资源
      最近更新 更多