【问题标题】:Minimizing time complexity when looping over two arrays循环两个数组时最小化时间复杂度
【发布时间】:2020-03-23 19:26:23
【问题描述】:

对于计算机科学入门课程,我们必须编写一个函数来查找两个数组的交集,每个唯一元素只显示一次,并且不会分配超出我们需要的空间。

例如:

数组 A = {1, 2, 3, 3, 3, 5}

数组 B = {2, 2, 2, 3, 5, 6}

A 和 B 的交点 = {2, 3, 5}

如何在不循环两个数组两次的情况下完成此操作?就目前而言,我有:

//find how large of an array I'll need
for array A 
  for array A
    if A[i] is already somewhere earlier in array A
      stop
    else 
      loop through array B 
      if A[i] is in array B, increment a counter


declare a new array of size counter  

//add unique elements to the array
for array A 
  for array A
    if A[i] is already somewhere earlier in array A
      stop
    else 
      loop through array B 
      if A[i] is in array B, add it to the new array

这似乎真的很低效我有两个几乎相同的嵌套 for 循环。如果我使用 python,我可以将唯一元素附加到列表中,但是有没有办法可以在 C 中做类似的事情?我可以只声明一个我可能需要的最大大小的数组,但我试图最小化空间复杂度。

【问题讨论】:

  • 数组是否保证被排序,就像在你的例子中一样?如果是这样,那么您可以用两根手指步行。
  • 不,我在制作示例时没有考虑到这一点。
  • 嗯,一种方法是对两个数组进行排序,然后进行双指遍历。那将是 O(n*log(n)),而不是 O(n**2)。

标签: c for-loop time-complexity


【解决方案1】:

如果您知道集合,您可以使用它。时间复杂度为O(n)

您可以在Chere 中了解更多关于 set 以及如何实现其中一个。

然后你可以做这样的事情(用Java写的):

public int[] intersection(int[] nums1, int[] nums2) {
    Set<Integer> set1 = getSet(nums1);
    Set<Integer> set2 = getSet(nums2);

    Set<Integer> ans = new HashSet<>();

    for(Integer i: set1) {
        if(set2.contains(i)) {
            ans.add(i);
        }
    }

    int[] ret = new int[ans.size()];

    int count = 0;
    for(Integer i: ans) {
        ret[count] = i;
        count++;
    }

    return ret;
}

public Set<Integer> getSet(int[] arr) {
    Set<Integer> set = new HashSet<>();

    for(int a: arr) { set.add(a); }
    return set;
} 

【讨论】:

  • C 问题的 Java 答案?哪里 C 没有原生集合?
  • @GregA.Woods 为此添加了链接。
猜你喜欢
  • 1970-01-01
  • 2011-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-08
相关资源
最近更新 更多