在所有数组中找出最小的公用数

时间:2019-11-07 11:51:31

标签: javascript arrays

任务:

  

您将获得3个排序的数组。您应该找到最小的数字   这在所有3个数组中都是常见的,并返回它。如果没有这样的数字   存在,返回-1

我的方法:

  1. 使用提前退出:如果数组之一为空,那么我们知道在所有数组中都不会有一个公共数字
  2. 创建指向相应数组第一个元素的指针
  3. 在外部循环中,循环遍历第一个数组的所有元素。如果任何指针到达数组的末尾,请中断循环,因为我们已经到达末尾并且尚未找到一个公共数字
  4. 在第一个内部循环中,检查第二个数组中第一个数组的指针所指向的元素
  5. 如果找到它,则设置一个标志。否则请记住第二个指针的运行索引,以便我们可以在下一次迭代中继续该元素
  6. 如果设置了标志,则在第二个内部循环中循环。在这里,它类似于第一个内部循环:在第3个数组中搜索当前元素。
  7. 如果找到它,则立即返回该值。如果没有找到下一个元素,请转到下一个元素
  8. 增加第一个数组的指针
  9. 执行此操作,直到到达阵列中的任何一个

我的解决方案:

let findLeastCommonNumber = function(a, b, c) {
    if (a.length === 0 || b.length === 0 || c.length === 0) {
      return -1;
    }
    let aPointer = 0;
    let bPointer = 0;
    let cPointer = 0;

    while (aPointer < a.length ||
           bPointer < b.length || 
           cPointer < c.length) {
        const aValue = a[aPointer];
        let bFound = false;
        for (let i = bPointer; i < b.length; i++) {
            if (b[i] === aValue) {
                bPointer = i;
                bFound = true;
                break;
            }
            if (b[i] > aValue) {
                bPointer = i;
                break;
            }
        }
        if (bFound) {
            for (let i = cPointer; i < c.length; i++) {
                if (c[i] === aValue) {
                    return a[aPointer];
                }
                if (c[i] > aValue) {
                    cPointer = i;
                    break;
                }
            }
        }
        aPointer++;
    }
    return -1;
};

示例解决方案:

let find_least_common_number = function(a, b, c) {
    let i = 0;
    let j = 0;
    let k = 0;

    while (i < a.length
    && j < b.length 
    && k < c.length) {

        // Finding the smallest common number
        if (a[i] === b[j]
        && b[j] === c[k]) {
            return a[i];
        }

        // Let's increment the iterator
        // for the smallest value.

        if (a[i] <= b[j]
        && a[i] <= c[k]) {
            i++;
        } else if (b[j] <= a[i]
        && b[j] <= c[k]) {
            j++;
        } else if (c[k] <= a[i]
        && c[k] <= b[j]) {
            k++;
        }   
    }

    return -1;
};

我喜欢这样的事实,即样品溶液的嵌套较少。但是示例解决方案没有利用早期退出的优势,我认为我的解决方案具有更大的可扩展性。假设需求发生了变化,现在包括了27个阵列。在我的解决方案中,我只复制内部循环并仅更改指针名称。我不需要接触现有代码。但是,在示例解决方案中,我要触摸涉及数组之一的每一行代码,然后在其中添加新的数组。你觉得呢?

3 个答案:

答案 0 :(得分:2)

您可以使用完全动态的方法来处理无限数量的数组。

function findLeastCommonNumber(...array) {
    var indices = array.map(_ => 0),
        smallest = Math.max(...array.map((a, i) => a[indices[i]])),
        next;

    while (indices.every((i, j) => i < array[j].length)) {
        next = smallest;
        array.forEach((a, i) => {
            while (indices[i] < a.length && a[indices[i]] < smallest)
                next = Math.max(next, a[++indices[i]]);
        });
        if (array.every((a, i) => a[indices[i]] === smallest)) return smallest;
        smallest = next;
    }
    return -1;
}

console.log(findLeastCommonNumber([1, 2, 3, 4, 5, 7], [8, 9, 10], [1, 2, 3, 5, 6, 7, 9]));
console.log(findLeastCommonNumber([1, 2, 3, 4, 5, 7, 9, 10], [1, 2, 3, 5, 6, 7, 9, 10], [4, 6, 7, 8, 9, 10, 11, 12]));
console.log(findLeastCommonNumber([1, 5, 6, 7, 8, 10], [5, 6, 9, 10], [1, 2, 3, 4, 5, 6, 9, 10]));

答案 1 :(得分:1)

对于更具可读性的解决方案,您可以使用以下方法:

const findLeastCommonNumber = function() {
  const total = [].concat(...arguments).sort((a,b) => a > b ? 1 : -1);
  let index = 0;
  let commonNumber = -1;
  while(total.length - 2 > index && commonNumber === -1){
    if(total[index] === total[index + 1] && total[index] === total[index + 2]){
        commonNumber = total[index];
    }
    index++;
  }
  return commonNumber;
};

console.log(findLeastCommonNumber([1,5,6,7,8,10],[5,6,9,10],[1,2,3,4,5,6,9,10]));

答案 2 :(得分:1)

另一种解决方案-取第一个数组,然后将其他数组转换为Sets。现在在第一个数组上使用labels=BeforeAndAfter,并用Array.find()检查是否在所有集合中都找到了当前数字。

Array.every()