【问题标题】:averagePair problem using multiple pointers as a solution使用多个指针作为解决方案的averagePair问题
【发布时间】:2020-10-19 23:04:33
【问题描述】:

我正在尝试解决以下问题:

到目前为止我的想法:

function averagePair(arr,tar){

    if (arr.length < 2){
        return false
    }

    let x = 0

    for (var y = 1; y < arr.length; y++){
        if ((arr[x] + arr[y]) / 2 == tar){
            return true
        }
        else {
            x++;
        }
    }
    return false
}

我知道这个解决方案不正确,有人可以解释原因吗?它适用于某些情况,但不是全部

【问题讨论】:

    标签: javascript algorithm pointers average


    【解决方案1】:

    O(1) 额外空间复杂度和O(n) 时间复杂度的解决方案。

    由于数组已排序,因此有两个索引是有意义的:一个从开始到结束(比如y),另一个从数组的一端到开始(比如x)。

    代码如下:

    function averagePair(arr,tar){
        
        // That's now included in for-loop condition
        // if (arr.length < 2) {
        //     return false;
        // }
    
        let x = arr.length - 1;
    
        for (var y = 0; y < x; y++) {
    
            // Division may lose precision, so it's better to compare
            //   arr[x] + arr[y] > 2*tar
            // than
            //   (arr[x] + arr[y]) / 2 > tar
    
            while (y < x && arr[x] + arr[y] > 2*tar) {
                x--;
            }
            if (x != y && arr[x] + arr[y] == 2*tar) {
                return true;
            }
        }
        return false;
    }
    

    这是一种双指针技术:对于当前循环迭代,我们将减少 x 直到 a[x] + a[y] &gt; 2*tar,因为我们需要找到最接近的匹配。在下一次 for 循环迭代中,a[y] 大于或等于前一次,因此检查 a[z] + a[y] == 2*tar 是否为任何 z &gt; x 是没有意义的。我们会这样做,直到索引不相等,这意味着没有匹配。

    【讨论】:

    • 感谢您的解释!你到底是什么意思,除法会失去精度?
    • @sofiat123 在这种特殊情况下除以 2 不会导致任何问题,但通常如果可以的话最好避免浮点计算(例如,参见 this
    【解决方案2】:

    您只是在比较相邻元素,例如[0][1],以及[1][2]。您还需要比较 [0][2] 等等。最简单的调整是使用嵌套循环:

    for (let x = 0; x < arr.length; x++) {
      for (let y = 0; y < arr.length; y++) {
        if (x !== y) {
          // test arr[x] against arr[y]
    

    但是使用 Set 来跟踪迄今为止发现的内容会更优雅且计算复杂度更低(O(n) 而不是O(n ^ 2)):

    const nums = new Set();
    for (const num of arr) {
      if (nums.has(tar - num)) {
        return true;
      } else {
        nums.add(num);
      }
    }
    

    function averagePair(arr,tar){
      const nums = new Set();
      for (const num of arr) {
        if (nums.has(tar - num)) {
          return true;
        } else {
          nums.add(num);
        }
      }
      return false;
    }
    
    console.log(averagePair([-2, 3, 2], 0));
    console.log(averagePair([-2, 3, 3], 0));

    【讨论】:

    • 我明白了 - 任何想法如何在没有嵌套循环的情况下进行。这个问题需要 O(N) 时间复杂度
    • 改用一个集合。
    猜你喜欢
    • 1970-01-01
    • 2020-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-31
    相关资源
    最近更新 更多