2017-08-28 43 views
1

我给了一个双打数组,所有数字除了一个都相等。我的任务是找到唯一的号码。我的代码返回正确的输出,现在我想知道如何进一步优化它。如何进一步优化我的代码?

这是我的代码:

public static double findUnique(double array[]) { 
    double unique = 0; 
    double common = 0; 

    for(int i=0; i<array.length; i++) { 
     for(int j=i+1; j<array.length; j++) { 
      if(array[i]==array[j]) { 
       common = array[i]; 
      } 
     } 
     if(common!=array[i]) { 
      unique = array[i]; 
     } 
    } 
return unique; 
} 

我能想到的首先是存储数组的长度的唯一的事情,但有些测试后实际所花的时间。谢谢。

+0

好吧,现在我觉得没有测试这个愚蠢。我在'if'语句中使用了'break',这大大减少了所需的时间。尽管如此,我仍然愿意回答。 – Helquin

+2

真的很容易。看看'array [0]','array [1]','array [2]'。如果它们中的任何一个与其他的不同,则返回唯一的一个。如果全部相同,则在'array [3 ... N-1]'中搜索**不等于'array [0]'的一个元素。 –

+0

@IwillnotexistIdonotexist谢谢你的建议,我会根据这个做一个新的方法。 – Helquin

回答

3
public static double findUnique(double array[]) { 
    if(array.length < 3) { 
     throw new IllegalArgumentException("wrong array"); 
    } 

    double common; 
    if(array[0] == array[1]) { 
     common = array[0]; 
    } else { 
     return array[0] != array[2]? array[0]: array[1]; 
    } 

    for(int i=2; i<array.length; i++) { 
     if(common != array[i]) { 
      return array[i]; 
     } 
    } 
    throw new IllegalArgumentException("wrong array"); 
} 
+0

'if(array.length <3)'部分似乎是为codewars kata制作的。仍然比我的代码更好。 – Helquin

+0

如果(array.length <3)不需要,你可以不使用它。我写它的一般情况下,如有可能有错误的论点。 –

+0

对不起,我刚才意识到一个长度小于3的数组只有两个不同的元素永远不会有唯一的,也没有公共元素。 – Helquin

2

我相信它在everey迭代中抓住两个新数字是不必要的。

取而代之,我们可以从抓取数组的两个第一个数字开始,然后如果这些数字相同,我们可以将其余数字与它们的值进行比较。所以我们在for循环之上定义了我们的公共元素,这样我们就可以避免在每次迭代中使用for循环和if语句:common = array [i]。我相信这应该在速度上有所作为,至少如果数组是疯狂的大的话。^^

另外,把回路放在for循环中,这样你就不会遍历整个列表,即使你真的发现一块金子:) :)。 (返回的东西总是打破整个方法。)

希望我不要错过任何东西:)。这里有一些代码给你。 :)

public static double findUnique(double array[]) { 
    double common = 0; 

    if(array.length<3){ 
    throw new IllegalArgumentException("Only two numbers exsists"); 
    } 

    // Set up the common number seperately here. 
    if(array[0] == array[1]){ 
     common = array[0]; 
    } 
    else if(array[1] == array[2]){ 
     return array[0]; 
    }else{ 
     return array[1]; 
    } 
    // Now we iterate with return inside the for loop. 
    for(int i=2; i<array.length; i++) { 
     if(common!=array[i]) { 
     return array[i]; 
     } 
    } 
throw new IllegalArgumentException("All numbers are identical"); 

} 
+0

变量唯一根本不需要,可以使用只返回数组[0],返回数组[1]和返回数组[i];之后for(...)必须返回或抛出,或者你有编译异常。 –

+1

你是对的!而你在哪里更快! :)我的概念是健全的(希望^^)。 – Axiomel

0

如果您先排列整个阵列,该怎么办?然后看看数组的前两个元素和最后一个元素。

+0

当然,它会工作,但问题是关于优化。为了找到一个单独的异常值(最坏情况下的N复杂度)而对整个阵列进行排序(通常为Nlog(N)复杂度)可能不是最佳解决方案。 – GPI

+0

是的,没错。只是它可以两种方式。想知道如果我们在第二个最后的位置找到独特的元素。再想一想,你是对的,这将是一个矫枉过正的问题。 – Gautam

+0

不确定它可以“双向”。对列表进行排序可以保证比N比较多**。查找异常值保证至多需要** N(+1)个比较。 – GPI