Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么我的配对查找器的复杂度很低,需要改进什么_Java_Arrays_Performance_Linked List_Time Complexity - Fatal编程技术网

Java 为什么我的配对查找器的复杂度很低,需要改进什么

Java 为什么我的配对查找器的复杂度很低,需要改进什么,java,arrays,performance,linked-list,time-complexity,Java,Arrays,Performance,Linked List,Time Complexity,在完成这项挑战时,由于我的解决方案的复杂性,我的得分很低,我得到了O(n2),但我不明白为什么,因为我觉得它应该运行得更快,而且在代码方面它非常紧凑且高效: 任务简介: 我被要求做的是: 我的代码如下: import java.util.LinkedList; 类解决方案{ 公共int解决方案(int[]A){ LinkedList checkedNumbers=新建LinkedList(); for(int i=0;i

在完成这项挑战时,由于我的解决方案的复杂性,我的得分很低,我得到了
O(n2)
,但我不明白为什么,因为我觉得它应该运行得更快,而且在代码方面它非常紧凑且高效: 任务简介:

我被要求做的是:

我的代码如下:

import java.util.LinkedList;
类解决方案{
公共int解决方案(int[]A){
LinkedList checkedNumbers=新建LinkedList();
for(int i=0;i对于(intx=0;x使用
ArrayList
和嵌套循环会给您二次时间复杂度(
O(n^2)
)。使用
LinkedList
会使情况更糟,因为(如talex所评论),
get
remove
take
O(n)
LinkedList
中的时间,因此您的代码的时间复杂度为
O(n^4)`

如果改用
HashSet
,则添加、删除和查找元素需要
O(1)
时间,因此总运行时间将是线性的(
O(n)

public int解决方案(int[]A){
Set checkedNumbers=new HashSet();
for(int i=0;i
正如评论中所建议的,我的代码需要改进一点:

public int solution(int[] A) {
    Set<Integer> checkedNumbers = new HashSet<>();
    for (Integer number : A) {
        if (!checkedNumbers.add(number)) { // try to add the element
            checkedNumbers.remove(number); // remove it if it's already in the Set
        }
    }
    return checkedNumbers.iterator().next();
}
public int解决方案(int[]A){
Set checkedNumbers=new HashSet();
for(整数:A){
如果(!checkedNumbers.add(number)){//请尝试添加元素
checkedNumbers.remove(number);//如果已在集合中,则将其删除
}
}
返回checkedNumbers.iterator().next();
}

有一个技巧可以在不使用任何复杂数据结构的情况下解决此问题:

int v = 0;
for (int a : A) {
  v ^= a; // Compound exclusive or.
}
return v;
此处使用的复合异或赋值运算符将“翻转”与
a
中值为1的位对应的
v
中的位

这是因为
a^a≡ 0
(和
a^b≡ b^a
,和
(a^b)^c≡ a^(b^c)
,和
a^0≡ a
),因此第一次观察
a
的位被第二次观察
a
的位抵消

最后将在
v
中设置的唯一位是来自未配对元素的位

例如,如果数组包含
[a,b,a,b,u]
(因此
u
是未配对的元素):


很好的解释和算法;我可以建议使用<代码>(int v:a)<代码>一个显式索引(但是这是非常可读的)。@ ELIOTTFRISCH也可以考虑将循环变量声明为<代码>整数< /代码>以避免装箱两次。代码的时间复杂度为O(n ^ 4)(最坏情况)。
LinkedList
中的
get
remove
具有线性复杂度。
public int solution(int[] A) {
    Set<Integer> checkedNumbers = new HashSet<>();
    for (Integer number : A) {
        if (!checkedNumbers.add(number)) { // try to add the element
            checkedNumbers.remove(number); // remove it if it's already in the Set
        }
    }
    return checkedNumbers.iterator().next();
}
int v = 0;
for (int a : A) {
  v ^= a; // Compound exclusive or.
}
return v;
  a ^ b ^ a ^ b ^ u
= (a ^ a) ^ (b ^ b) ^ u
= 0 ^ 0 ^ u
= u