面试题 16.06. 最小差

135 阅读1分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

题目描述

  • 给定两个整数数组ab,计算具有最小差绝对值的一对数值(每个数组中取一个值),并返回该对数值的差。
  • 提示
  1. 1<=a.length,b.length<=1000001 <= a.length, b.length <= 100000
  2. 2147483648<=a[i],b[i]<=2147483647-2147483648 <= a[i], b[i] <= 2147483647
  3. 正确结果在区间 [0,2147483647][0, 2147483647]示例 1
输入:{1, 3, 15, 11, 2}, {23, 127, 235, 19, 8}
输出:3,即数值对(11, 8)

思路分析

  • 假设 aa 整数数组的长度为 mmbb 整数数组的长度为 nn

  • 暴力方法分析:对于 aa 中的每个整数都对 bb 中所有的整数取差值,维护并返回最小的一个差值。时间复杂度为:O(mn)O(m*n),空间复杂度为:O(1)O(1) 。在最坏情况下时间复杂度达到 O(10109)O(10 * 10 ^ 9)

  • 双指针方法分析:通过观察发现,可以将两个整数数组先进行排序,然后可以从两数组的头部或者尾部对两数组的两个元素进行逼近取差值。因为在逼近的过程中我们可以尽最大可能取到最小差值。主要的时间开销在于整数数组的排序上,所以时间复杂度为:O(mlog(m)+nlog(n))O(m*log(m) + n*log(n)),空间复杂度为:O(1)O(1)

AC 代码

  • 暴力方法实现代码
public int smallestDifference(int[] a, int[] b) {
        int m = a.length;
        int n = b.length;
        long min = Integer.MAX_VALUE;
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                min = Math.min(min, Math.abs(a[i] - b[j]));
            }
        }
        return (int)min;
    }
  • 双指针方法实现代码
class Solution {
    public int smallestDifference(int[] a, int[] b) {
        int m = a.length;
        int n = b.length;
        Arrays.sort(a);
        Arrays.sort(b);
        int index_a = 0;
        int index_b = 0;
        long min = Integer.MAX_VALUE;
        while (index_a < m && index_b < n) {
            long value_a = a[index_a];
            long value_b = b[index_b];
            if (value_a < value_b) {
                min = Math.min(min, value_b - value_a);
                index_a++;
            } else if (value_a > value_b) {
                min = Math.min(min, value_a - value_b);
                index_b++;
            } else {
                return 0;
            }
        }
        return (int)min;
    }
}

总结

  • 又是一道运用双指针的题目,难度不大,很适合练习双指针使用。