【问题标题】:How do I further optimize my code?如何进一步优化我的代码?
【发布时间】:2017-08-28 08:52:10
【问题描述】:

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

这是我的代码:

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;  
}

我唯一能想到的就是先存储数组的长度,但经过一些测试后,它实际上需要更长的时间。谢谢。

【问题讨论】:

  • 好的,现在我因为不测试这个而感到愚蠢。我在if 语句中使用了break,它大大减少了所需的时间。不过,我仍然愿意接受答案。
  • 真的很简单。看看array[0]array[1]array[2]。如果其中任何一个与其他不同,则返回唯一的。如果都相同,则在array[3...N-1] 中搜索 等于array[0] 的一个元素。
  • @IwillnotexistIdonotexist 谢谢你的建议,我会在此基础上做一个新的方法。

标签: java for-loop


【解决方案1】:
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"); 
}

【讨论】:

  • if(array.length&lt;3) 部分似乎是为 codewars kata 制作的。仍然比我的代码好。
  • 如果 if(array.length
  • 对不起,我刚刚意识到长度小于 3 并且只有两个不同元素的数组永远不会有唯一或公共元素。
  • 任何人在循环之前将 arr.Length 放入变量中,例如 int arrLen = array.length;这将进一步优化它。
  • @Amit :我相信这是理论上的收获,而不是实际的收获(至少在我的长凳上是这样)。另见:stackoverflow.com/questions/1208320/…
【解决方案2】:

我相信在每次迭代中获取两个新数字是不必要的。

相反,我们可以从获取数组的前两个数字开始,然后如果这些数字相同,我们可以将其余数字与它们的值进行比较。所以我们在 for 循环之上定义我们的 common,这样我们将避免 for 循环和 if 语句在每次迭代中包含: common= array[i]。我相信这应该会在速度上有所不同,至少如果数组非常大的话。^^

另外,将 return 放在 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]、返回数组[1]和返回数组[i];同样在 for(...) 之后必须是 return 或 throw,否则你有编译异常。
  • 你说得对!而你在哪里更快! :) 我的概念是合理的(希望^^)。
【解决方案3】:

如果先对整个数组进行排序会怎样。然后只看数组的前两个和最后一个元素。

【讨论】:

  • 当然可以,但问题是关于优化。仅出于查找单个异常值(最坏情况下 N 复杂度)的目的而对完整数组(通常为 Nlog(N) 复杂度)进行排序可能不是最佳解决方案。
  • 是的,没错。只是它可以双向进行。想知道如果我们在倒数第二个位置找到唯一元素会怎样。再想一想,你是对的,这将是一个矫枉过正。
  • 不确定它是否可以“双向”。保证对列表进行排序会进行 更多 次比较。保证找到异常值需要最多 N(+1 ?) 次比较。
  • 试过了,执行时间明显变长了。
猜你喜欢
  • 2015-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-19
  • 2023-02-09
  • 1970-01-01
相关资源
最近更新 更多