Javascript 效率:整数数组子集中两个项之间的最大差值

Javascript 效率:整数数组子集中两个项之间的最大差值,javascript,Javascript,我正在参加一个编程考试,任务是为一个特定的问题编写高效的代码。我相信我得到了正确的答案(在5个测试场景中有3个是有效的),但其余两个测试场景(我没有详细说明)由于耗时超过2秒而失败 我使用.slice和.apply()克隆一个子数组并获取其中的最大/最小值。这是最慢的部分,我能做些什么来改进它 我的代码: function find_deviation(v, d) { var maxMedian = 0; var i = 0; var len = v.length - d

我正在参加一个编程考试,任务是为一个特定的问题编写高效的代码。我相信我得到了正确的答案(在5个测试场景中有3个是有效的),但其余两个测试场景(我没有详细说明)由于耗时超过2秒而失败

我使用
.slice
.apply()
克隆一个子数组并获取其中的最大/最小值。这是最慢的部分,我能做些什么来改进它

我的代码:

function find_deviation(v, d) {
    var maxMedian = 0;
    var i = 0;
    var len = v.length - d + 1;
    var sequence, min, max, median;
    for(;i < len; ++i) {
        sequence = v.slice(i, i+d);
        min = Math.min.apply(null, sequence);
        max = Math.max.apply(null, sequence);
        median = max - min;
        if(median > maxMedian) {
            maxMedian = median;
        }
    }
    console.log(maxMedian);
}
函数查找偏差(v,d){
var最大中值=0;
var i=0;
var len=v.长度-d+1;
var序列,最小值,最大值,中值;
对于(;i最大中值){
最大中值=中值;
}
}
console.log(最大中值);
}
问题是:


长度为
d
项的数组
v
子集中的两个项之间的最大差异(
maxmidian
)是多少?
v
数组中的所有项都是整数,以及
d

首先,我是否正确地假设您希望在大小为
d
的所有紧凑子数组中找到最大差异

如果是这样,那么从我的头顶上我可以看到两个问题:

  • 阵列切片的开销
  • Math.min
    Math.max
    的复杂度是O(n),当您执行这两个操作时,它会产生O(2n)
为了解决这两个问题,我提出了以下建议:

function find_deviation(v, d) {
    var maxDifferenceGlobal = 0;
    var len = v.length - d + 1;
    for(var i = 0; i < len; ++i) {
        var min, max;
        if (v[i] <= v[i + 1]) {
            min = v[i]; max = v[i + 1];
        } else {
            max = v[i]; min = v[i + 1];
        }
        for(var j = i + 2; j < i + d; ++j) {
            if (min > v[j]) { min = v[j]; }
            if (max < v[j]) { max = v[j]; }
        }
        var maxDifferenceLocal = Math.abs(max - min);
        if(maxDifferenceLocal > maxDifferenceGlobal) {
            maxDifferenceGlobal = maxDifferenceLocal;
        }
    }
    console.log(maxDifferenceGlobal);
}
函数查找偏差(v,d){
var maxDifferenceGlobal=0;
var len=v.长度-d+1;
对于(变量i=0;imaxDifferenceGlobal){
maxDifferenceGlobal=maxDifferenceLocal;
}
}
log(maxDifferenceGlobal);
}

这样就消除了数组切片的开销,并在O(n)中同时找到
max
min
,因此仅通过常量就更好了,但效果不同。另外,你不应该使用
Math.abs
来计算差异吗?

我没有剪报,但在我看来,你不应该一遍遍地寻找最大值和最小值,只要看看子集尾部就足以确定如果你在整个子集上运行最小值/最大值,最大中值是否会上升……一个快捷方式,根据我之前的评论,就在for循环中:
if(v[i+d]min)continue
这是基于我的理论,即如果以前未看到的数字在以前的最小值/最大值内,它不会影响最大中值(或最小值/最大值),因此,您可以安全地继续,而无需截断新的子数组。我认为该理论不成立,因为长度d是固定的,因此在每次迭代中,序列也会丢失一个可能是以前的max/min的值。如果(I>0&&v[I+d]=min&&v[I-1]!=max&&v[I-1]!=min),您可以继续。您的解释对我很有意义,我的问题错误地漏掉了Math.abs,谢谢你指出这一点。由于您的答案没有使用数组
切片
应用
,因此这似乎更有效。不幸的是,我没有办法证明这一点,因为考试已经结束了。我认为数组函数的设计是高效的,但是您的方法使用更简单的逻辑来实现相同的结果。再次感谢您抽出时间提供帮助。@Quantastical:不客气:)至于分析这两个版本,我找到了一个用于测量和使用大小为1000000且
d==4
的数组的时间。您的版本的时间大约为500毫秒,而我的版本显示的时间大约为20毫秒,但我不知道该分析器有多精确:)