当前位置: 首页 > 知识库问答 >
问题:

以下代码的复杂性

阳俊德
2023-03-14

我被赋予以下任务:

给出了-2个列表。第一个列表的大小为N1,第二个列表的尺寸为N2。每个列表的元素不相同。编写一段代码,用第一个和第二个列表中的元素创建一个新列表。此列表也不应有相同的元素。还要估计代码的复杂性。

我编写了以下代码:

public class Lists {    
    static ArrayList<Integer> getNewList(ArrayList<Integer> list1, 
                                         ArrayList<Integer> list2) {
        ArrayList<Integer> tmp = new ArrayList<>();
        for (Integer i : list1) {
            tmp.add(i);
        }
        for (Integer i : list2) {
            if (!list1.contains(i)) 
                tmp.add(i);
        }
        return tmp;
    }

    public static void main(String[] args) { 
        Integer[] arr1 = {1, 2, 3, 14, 15, 16};        
        Integer[] arr2 = {3, 6, 7, 8, 14};
        ArrayList<Integer> list1 = new ArrayList<>(Arrays.asList(arr1));
        ArrayList<Integer> list2 = new ArrayList<>(Arrays.asList(arr2));
        for (Integer i : getNewList(list1, list2)) {
            System.out.print(i + " ");
        }
    }
}

并假设 getNewList 方法的执行时间与 N1*N2 成正比。在回复中,我收到以下内容,没有任何解释 - “你错了,这段代码的复杂性不是 N1*N2”。

那么有人能告诉我什么是正确的答案吗?并解释复杂性是如何决定的?

共有3个答案

尚安平
2023-03-14

我肯定在这里也看到了O(N1*N2)的复杂性。我猜你的教授忽略了包含调用的成本如下:

for (Integer i : list2) {
    if (!list1.contains(i)) 
        tmp.add(i);
}

ArrayList 上包含 O(N) 复杂度。由于 list2 上的循环也是 O(N),因此最终得到 O(N1 * N2)。

夏振国
2023-03-14

嗯,你这个问题的简短回答是:复杂度是N1 (N2*N1)/2 N3(新列表的大小),应该是O(N1*N2)

故障:

for (Integer i : list1) {
  tmp.add(i);
} 
-> clearly, this is N1
for (Integer i : list2) {
  if (!list1.contains(i)) 
    tmp.add(i);
} 
-> list2 iteration => N2
-> for each of this iteration, you call .contain method 
   which uses sequential search, resulting in N1/2 iterations (on average)
-> So, you get N2*N1/2

在main中,您有一个循环,从0迭代到N3(这是新List的长度)

所以,总的来说,你得到N1(N2*N1)/2 N3,应该是O(N1*N2)

戚飞
2023-03-14

代码的复杂度为< code>O(N1*N2),但是通过使用< code>HashSet来确定哪些数字出现在两个列表中,你可以做得更好:

static ArrayList<Integer> getNewList(ArrayList<Integer> list1, 
                                     ArrayList<Integer> list2) {
    ArrayList<Integer> tmp = new ArrayList<>();
    HashSet<Integer> dups = new HashSet<>();
    tmp.addAll(list1);
    dups.addAll(list1);
    for (Integer i : list2) {
        if (!dups.contains(i)) 
            tmp.add(i);
    }
    return tmp;
}

这将为您提供O(N1 N2)运行时间,因为在HashSet中插入和查找需要预期的O(1)时间。

 类似资料:
  • 以下代码是竞赛中问题陈述的解决方案。给出的时间限制为1s。该代码在5/7个测试用例中正常工作。对于其他情况,超过了时间限制。如何降低下面代码的时间复杂度? 编辑:问题陈述被定义为返回数字n的值或n/2、n/3、n/4之和,以最大值为准。例如,如果输入为24,则可以进一步减少或交换为12 8 6=26,12可以减少为6 4 3=13。8和6不应减少,因为这可能会降低值。最后的答案是13 8 6=27

  • 这个问题的正确答案是O(N)。但根据我的说法,答案应该是O(NlogN)。因为第一个“for循环”的复杂度应该是O(logN),因为在每次迭代中变量i被2除,而且我已经研究过,每当循环变量被2乘或除,那么时间复杂度就是O(logN)。现在,对于第二个“for循环”,复杂度应该是O(N),因此,最后一个复杂度应该是O(N*logn)。 谁能解释一下我错在哪里吗?

  • 我有以下代码,我需要重构它,以降低复杂性,增加模块化和封装性。我还需要减少ck度量值。 你如何重构这个代码?切换案例是否降低了复杂性?

  • 测量代码是否冗长的工具和度量 只是从远处看一眼乱七八糟四处蔓延的代码块,开发人员就会感到心惊肉跳 —— 这很正常!冗长的代码常常是复杂性的标志,会导致代码难以测试和维护。本月将学习三种测试代码复杂性的重要方法,它们分别基于方法长度、类长度和内部类耦合。在这一期的 追求代码质量 系列文章中,专家 Andrew Glover 将向您展示如何使用诸如 PMD 和 JavaNCSS 之类的工具,在您需要的

  • 目标 咱们在lesson4的基础上接着讲,这一节要解决两个问题: 1、第三方库的引入; 2、复杂项目下的按需加载。 知识点 1、使用extract-text-webpack-plugin打包多个css文件; 2、CommonsChunkPlugin:抽取公共模块; 3、ProvidePlugin:全局调用某模块; 4、require.ensure():按需加载模块。 课程内容 咱们还是以lesso

  • 有人能帮我了解一下这个代码片段的时间和空间复杂性吗?请参考leetcode问题-单词中断II。给定一个非空字符串s和一个包含非空单词列表的字典单词dict,在s中添加空格来构造一个句子,其中每个单词都是有效的字典单词。返回所有这些可能的句子。