【问题标题】:Error in finding minimum absolute difference between any two pair of elements in an array using javascript使用javascript查找数组中任意两对元素之间的最小绝对差时出错
【发布时间】:2019-04-28 04:55:49
【问题描述】:

我正在尝试解决一个程序,以使用 javascript 查找数组中任何一对元素之间的最小绝对差。输入将参数作为数组元素。输出返回数组中任意两个元素之间的最小绝对差

例如输入为[1,2,4],输出为1

问题的详细描述在this链接中给出。

在我的代码中,当给出包含 1000 个元素的输入数组时,它会编译并显示因超时而终止,但它适用于较小尺寸的输入数组

我认为错误来自性能和复杂性的问题。我研究了问题,但我不知道如何进行进一步的步骤

我的代码:

    var arr = [..] //array containing 1000 elements
    var count = minimumAbsoluteDifference(arr);
    console.log(count);
    function minimumAbsoluteDifference(arr) {
        var diff = []; var index = 0;
        arr.sort((a, b) => { return (a - b); });
        for (var i = 0; i < arr.length-1; i++){
            for (var j = i+1; j < arr.length; j++){
                if (i != j) {
                    diff[index] = Math.abs(arr[i] - arr[j]);
                    console.log("index", i, j);
                    index++;
                }
            }
        }
        var minAbsoluteDifference = Math.min(...diff);
        return minAbsoluteDifference;
    }

【问题讨论】:

  • 由于您的数组已经排序,您只需要找到 i 和 i+1 之间的最小差异,而不是 i 以及从 i+1 到 len 的所有差异。 diff[index] = Math.abs(arr[i] - arr[i+1]);

标签: javascript html arrays algorithm


【解决方案1】:

数组排序后,任意两个元素之间的最小绝对差必然在两个相邻元素之间。因此,您可以将嵌套的 for 循环 (O(N^2)) 更改为单个 for 循环 (O(N))(尽管排序函数仍然是 O(N log N),因此整体复杂性仅降低到 O(N log N) ):

function minimumAbsoluteDifference(arr) {
    var diff = [];
    arr.sort((a, b) => a - b);
    for (var i = 0; i < arr.length - 1; i++) {
        if (i < arr.length - 1) {
            diff.push(Math.abs(arr[i] - arr[i + 1]));
        }
    }
    var minAbsoluteDifference = Math.min(...diff);
    return minAbsoluteDifference;
}

这在大多数情况下都有效,但另一个问题是 HackerRank 似乎用不合理的大数组调用此函数(例如,单个数组中有 100000 个项目),所以

Math.min(...diff)

会导致

RangeError: 超出最大调用堆栈大小

改为在每次迭代时调用 Math.min

function minimumAbsoluteDifference(arr) {
    var lowestDiff = Infinity;
    arr.sort((a, b) => a - b);
    for (var i = 0; i < arr.length - 1; i++) {
        lowestDiff = Math.min(lowestDiff, Math.abs(arr[i] - arr[i + 1]));
    }
    return lowestDiff;

}

【讨论】:

  • Math.min 的优点,同时避免不必要地使用另一个 diff 数组。
  • @CertainPerformance...非常感谢您的回复...代码正在运行,您的建议对我帮助很大!
  • 您的解释非常清楚,可以理解代码
【解决方案2】:

  for (var i = 0; i < arr.length - 1; i++) {
      var j = i+1;//only check the diff with next neighbor
      diff[index] = Math.abs(arr[i] - arr[j]);
      console.log("index", i, j);
      index++;
  }

【讨论】:

  • @gp...非常感谢您的回复...代码正在运行,您的建议对我帮助很大!并且您的解释非常清楚,可以理解代码
【解决方案3】:

这是使用 Array.map 方法的好机会,因为它允许我们访问正在迭代的 currentValue、迭代的索引以及我们当前正在减少的数组。该函数的外观如下:

function minimumAbsoluteDifference(array) {
  const sortedArray = [...array].sort((a, b) => a - b);
  let difference = sortedArray[sortedArray.length - 1];

  sortedArray.map((currentValue, index, array) => {
    const currentMinDifference = Math.abs(currentValue - array[index + 1]);

    if (currentMinDifference < difference) {
      difference = currentMinDifference;
    }
  });

  return difference;
}

首先,我们对数组进行排序以使其更易于使用,然后我们将差值初始化为数组中的最大项。

然后我们在排序后的数组上调用map 方法,并使用提供的回调将 currentValue、索引和数组作为参数。

map 方法中,我们将计算当前数字与下一个数字之间的绝对差值。如果当前迭代的绝对差小于difference,那么我们在数组中发现了一个较小的绝对差。

这样一直持续到最后。

【讨论】:

  • 这是否超出了数组索引范围?
  • @65black...非常感谢您的回复...代码正在运行,您的建议对我帮助很大!并且您的解释很清楚,可以理解代码
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-02
  • 1970-01-01
  • 1970-01-01
  • 2021-01-31
相关资源
最近更新 更多