LeetCode 算法:最小差

165 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第 19 天,点击查看活动详情

最小差

原题地址

给定两个整数数组 ab,计算具有最小差绝对值的一对数值(每个数组中取一个值),并返回该对数值的差。

示例:

输入:{1, 3, 15, 11, 2}, {23, 127, 235, 19, 8}
输出:3,即数值对(11, 8)

提示:

  • 1 <= a.length, b.length <= 100000
  • -2147483648 <= a[i], b[i] <= 2147483647
  • 正确结果在区间 [0, 2147483647]

思路分析

方法一

  1. 分析题目可以得知,所需要的结果是一个最小值;
  2. 那么定义 res 为一个足够大的数值,为提示中的 2147483647
  3. 双层遍历 ab,然后取 resMath.abs(a[i] - b[j]) 的最小值;
  4. 循环结束后,返回 res 即可。这种方法最终耗时四千多毫秒。

方法二

  1. 首先将一个数组进行排序,然后使用另一个数组中的元素对已排序的数组进行二分查找;
  2. 定义一个辅助函数来进行二分查找,寻找一个差值最小的值;
  3. 然后对另一个数组进行遍历,因为 res 是定义在全局的,辅助函数中处理的最小值就是最后返回的 res 值。

AC 代码

方法一

/**
 * @param {number[]} a
 * @param {number[]} b
 * @return {number}
 */
var smallestDifference = function(a, b) {
    let res = 2147483647
    for(let i = 0; i < a.length; i++) {
        for(let j = 0; j < b.length; j++) {
            res = Math.min(res, Math.abs(a[i] - b[j]))
        }
    }
    return res
};

结果:

  • 执行结果: 通过
  • 执行用时:4556 ms, 在所有 JavaScript 提交中击败了24.18%的用户
  • 内存消耗:45.7 MB, 在所有 JavaScript 提交中击败了98.69%的用户
  • 通过测试用例:60 / 60

方法二

/**
 * @param {number[]} a
 * @param {number[]} b
 * @return {number}
 */
var smallestDifference = function(a, b) {
    a.sort((a,b) => a - b)
    let res = 2147483647
    function find(t) {
        let left = 0
        let right = a.length - 1
        while (left < right) {
            let middle = Math.floor((left + right) / 2)
            if (a[middle] >= t) right = middle
            else left = middle + 1
        }
        res = Math.min(res, Math.abs(a[left] - t))
        if (left > 0) {
            res = Math.min(res, Math.abs(a[left - 1] - t))
        }
    }
    for (let t of b) {
        if (res === 0) return 0
        find(t)
    }
    return res
};

结果:

  • 执行结果: 通过
  • 执行用时:132 ms, 在所有 JavaScript 提交中击败了84.31%的用户
  • 内存消耗:49.5 MB, 在所有 JavaScript 提交中击败了33.99%的用户
  • 通过测试用例:60 / 60

END