【问题标题】:Find the maximum element which is common in two arrays?找出两个数组共有的最大元素?
【发布时间】:2012-06-21 15:29:57
【问题描述】:

给定两个数组,如何找到两个数组共有的最大元素?

我正在考虑对两个数组进行排序(n log n),然后对另一个数组中的一个排序数组(从较大的数组开始)中的每个元素执行二进制搜索,直到找到匹配项。

例如:

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

Maximum common element in these array is 3

我们能比 n log n 做得更好吗?

【问题讨论】:

  • 并不是说它有助于整体复杂性,但在你的最后一步中,当你发现一个太小的值时,线性搜索可能会比二分搜索更快。每次您都可以从上次中断的地方重新启动它(而不是从头开始),因为您要查找的值小于您查找的最后一个值。所以搜索的总时间是 O(“另一个数组”的大小),在“一个排序数组”的元素之间分配不均匀。您还可以进行插值搜索等。

标签: algorithm


【解决方案1】:

有了一些额外的空间,您可以在 1 个数组中散列,然后在另一个数组的每个元素上执行包含,以跟踪返回 true 的最大值。将是 O(n)。

【讨论】:

  • 只要打败我就行了。当然,如果哈希不是唯一的,时间复杂度可能会更高一些(验证哈希匹配是否是实际匹配需要搜索)......如果哈希是唯一的,则会产生 O(n) 存储成本。
【解决方案2】:

您可以使用O(N) 空格。
只需遍历第一个数组并将所有元素放在HashTable 中。这是O(N)
然后通过第二个数组跟踪当前最大值并检查元素是否在HashTable 中。这也是O(N)。 所以总运行时间是O(N)O(N) HashTable 的额外空间

Java 示例:

public static int getMaxCommon(int[] a, int[] b){  
  Set<Integer> firstArray = new HashSet<Integer>(Arrays.asList(a));  
  int currentMax = Integer.MIN_VALUE;  
  for(Integer n:b){  
     if(firstArray.contains(n)){  
         if(currentMax < n){  
              currentMax = n  
         }
     }   
  }   
  return currentMax;  
}  

【讨论】:

    【解决方案3】:

    虽然这取决于特定语言中各种操作的时间复杂度,但如何从数组创建集合并在两个集合的交集处找到最大值?根据 Python 中操作的时间复杂度,平均而言,集合分配为 O(n),交叉点为 O(n),找到最大值为 O(n)。所以平均情况是 O(n)。

    但是!最坏情况是 O(len(a) * len(b)) -> O(n^2),因为集合交点的最坏情况时间复杂度。

    更多信息在这里,如果你有兴趣:http://wiki.python.org/moin/TimeComplexity

    【讨论】:

      【解决方案4】:

      如果您已经知道数组中的数字范围,则可以执行计数排序,然后执行所需的二进制搜索。这将产生 O(n) 运行时间。

      【讨论】:

        【解决方案5】:

        伪代码:

        sort list1 in descending order
        sort list2 in descending order
        item *p1 = list1
        item *p2 = list2
        while ((*p1 != *p2) && (haven't hit the end of either list))
          if (*p1 > *p2)
            ++p1;
          else
            ++p2;
        // here, either we have *p1 == *p2, or we hit the end of one of the lists
        if (*p1 == *p2)
          return *p1;
        return NOT_FOUND;
        

        【讨论】:

        • sort list1 in descending orderO(N) 操作吗?我不这么认为。除非你想出了一个 O(N) 排序算法
        • 除非你发现了一种新的排序算法。排序仍然为 O(n log n) + 扫描为 O(N) = O(N log n) 整体。我敢肯定,除非您能在一开始就对列表的顺序做出某些假设,否则您将无法做得更好。
        • OP 已经知道他可以以排序为代价使用排序作为预处理步骤。 OP 是关于 O(N) 的方法。如果你清楚地排序它不是,因此我对计算一个新的排序算法的评论
        • @user384706 OP 对 O(N) 只字未提,只是询问我们是否可以做得比 O(N log N) 更好。我认为另一个答案中提到的散列和扫描选项可能是最好的路线,并且可以接近 O(N),但在病态情况下,散列冲突仍可能使其成为 O(N log N)。
        • "排序是 O(N) 操作吗?" - 可能是通过(无聊的迂腐)对固定宽度的数字数据使用二进制基数排序。
        【解决方案6】:

        不是完美,而是简单的解决方案,O(len(array1) + len(array2))

        import sys
        
        
        def find_max_in_common(array1, array2):
            array1 = set(array1)
            array2 = set(array2)
        
            item_lookup = {}
        
            for item in array1:
                item_lookup[item] = True
        
            max_item = -sys.maxsize
        
            intersection = False
        
            for item in array2:
                if not item_lookup.get(item, None):
                    continue
                else:
                    intersection = True
                    if item > max_item:
                        max_item = item
        
            return None if not intersection else max_item
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-12-10
          • 2021-03-07
          • 2017-04-19
          • 1970-01-01
          • 1970-01-01
          • 2020-03-26
          • 2022-11-20
          • 1970-01-01
          相关资源
          最近更新 更多