Java 以下代码的复杂性
我被赋予以下任务: 给定-2个列表。第一个列表的大小为N1,第二个列表的大小为N2。每个列表的元素并不相同。 编写一段代码,用第一个和第二个列表中的元素创建一个新列表。此列表也不应包含相同的元素。 还要估计代码的复杂性 我编写以下代码:Java 以下代码的复杂性,java,algorithm,performance,Java,Algorithm,Performance,我被赋予以下任务: 给定-2个列表。第一个列表的大小为N1,第二个列表的大小为N2。每个列表的元素并不相同。 编写一段代码,用第一个和第二个列表中的元素创建一个新列表。此列表也不应包含相同的元素。 还要估计代码的复杂性 我编写以下代码: public class Lists { static ArrayList<Integer> getNewList(ArrayList<Integer> list1,
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 + " ");
}
}
}
公共类列表{
静态ArrayList getNewList(ArrayList list1,
ArrayList(列表2){
ArrayList tmp=新的ArrayList();
for(整数i:list1){
tmp.add(i);
}
for(整数i:list2){
如果(!list1.contains(i))
tmp.add(i);
}
返回tmp;
}
公共静态void main(字符串[]args){
整数[]arr1={1,2,3,14,15,16};
整数[]arr2={3,6,7,8,14};
ArrayList list1=新的ArrayList(Arrays.asList(arr1));
ArrayList list2=新的ArrayList(Arrays.asList(arr2));
for(整数i:getNewList(列表1、列表2)){
系统输出打印(i+“”);
}
}
}
假设getNewList方法的执行时间与N1*N2成正比。作为回复,我收到了以下没有任何解释的信息——“你错了,这段代码的复杂性不是N1*N2”
有人能说出正确答案吗?并解释复杂性是如何确定的?您的代码的复杂性是
O(N1*N2)
,但使用哈希集来确定两个列表中出现的数字,您可以做得更好:
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;
}
静态ArrayList getNewList(ArrayList list1,
ArrayList(列表2){
ArrayList tmp=新的ArrayList();
HashSet dups=新HashSet();
tmp.addAll(列表1);
dups.addAll(列表1);
for(整数i:list2){
如果(!dups.包含(i))
tmp.add(i);
}
返回tmp;
}
这将为您提供O(N1+N2)
运行时间,因为插入和查找需要O(1)
时间在HashSet
中。代码的复杂性是O(N1*N2)
,但您可以使用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;
}
静态ArrayList getNewList(ArrayList list1,
ArrayList(列表2){
ArrayList tmp=新的ArrayList();
HashSet dups=新HashSet();
tmp.addAll(列表1);
dups.addAll(列表1);
for(整数i:list2){
如果(!dups.包含(i))
tmp.add(i);
}
返回tmp;
}
这将给您O(N1+N2)
运行时间,因为插入和查找需要O(1)
时间在HashSet
感谢@Slanec的解释,我重新检查了JDK中contains(objectobj)
的实现,发现如下所示
public boolean contains(Object obj) {
return indexOf(obj) >= 0;
}
public int indexOf(Object obj) {
if (obj == null) {
for (int i = 0; i < size; i++)
if (elementData[i] == null)
return i;
} else {
for (int j = 0; j < size; j++)
if (obj.equals(elementData[j]))
return j;
}
return -1;
}
公共布尔包含(对象obj){
返回索引of(obj)>=0;
}
public int indexOf(对象对象对象){
if(obj==null){
对于(int i=0;i
显然,contains(objectobj)
的时间复杂度是O(n)。(起初我以为是O(1)
因此代码的时间复杂度应该是O(N1*N2),而不是O(n) 感谢@Slanec的解释,我重新检查了JDK中contains(objectobj)
的实现,发现如下所示
public boolean contains(Object obj) {
return indexOf(obj) >= 0;
}
public int indexOf(Object obj) {
if (obj == null) {
for (int i = 0; i < size; i++)
if (elementData[i] == null)
return i;
} else {
for (int j = 0; j < size; j++)
if (obj.equals(elementData[j]))
return j;
}
return -1;
}
公共布尔包含(对象obj){
返回索引of(obj)>=0;
}
public int indexOf(对象对象对象){
if(obj==null){
对于(int i=0;i
显然,contains(objectobj)
的时间复杂度是O(n)。(起初我以为是O(1)
因此代码的时间复杂度应该是O(N1*N2),而不是O(n) 我肯定也看到了O(N1*N2)
的复杂性。我猜你的教授忽略了下面的包含调用的成本:
for (Integer i : list2) {
if (!list1.contains(i))
tmp.add(i);
}
包含
在ArrayList上是O(N)
复杂度。由于您在列表2上的循环也是O(N)
,因此您最终会遇到O(N1*N2)
我肯定也看到了O(N1*N2)
的复杂性。我猜你的教授忽略了下面的包含调用的成本:
for (Integer i : list2) {
if (!list1.contains(i))
tmp.add(i);
}
包含
在ArrayList上是O(N)
复杂度。由于您在列表2上的循环也是O(N)
,您最终得到的是O(N1*N2)
好吧,您的问题的简短答案是:复杂性是N1+(N2*N1)/2+N3(新列表的大小),它应该是O(N1*N2)
细分:
for (Integer i : list1) {
tmp.add(i);
}
-> clearly, this is N1
在main中有一个循环,从0到N3(这是新列表的长度)进行迭代
所以,总的来说,你得到的是N1+(N2*N1)/2+N3,应该是O(N1*N2)你的问题的简单答案是:复杂性是N1+(N2*N1)/2+N3(新列表的大小),应该是O(N1*N2)
细分:
for (Integer i : list1) {
tmp.add(i);
}
-> clearly, this is N1
在main中有一个循环,从0到N3(这是新列表的长度)进行迭代
所以,总的来说,你得到的是N1+(N2*N1)/2+N3,应该是O(N1*N2)除非你能用一个实际的解释来证明我是错的,否则我会说不。第二个循环对列表2
中的每个元素进行检查,并对照列表1
。对列表的contains()
调用是线性的,O(N1),循环本身是显而易见的