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
和removetake
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