数列差异的最小化 | 豆包MarsCode AI刷题

88 阅读3分钟

问题概述:

我们有两个整数数列 ab,分别包含 nm 个元素,另外还给定一个整数 k。我们需要选择 a[i]b[j] 使得公式:

∣(a[i]−b[j])2−k2∣\left| (a[i] - b[j])^2 - k^2 \right|

的结果最小。也就是说,我们希望找到一对 (a[i], b[j]) 使得这个公式的值最接近 0。

核心思想:

这个问题的本质是通过遍历 ab 数列中的所有可能组合,计算公式的值,最终找到最小的值。关键步骤如下:

  1. 计算公式值: 对于每对 (a[i], b[j]),计算公式: value=∣(a[i]−b[j])2−k2∣\text{value} = \left| (a[i] - b[j])^2 - k^2 \right|
  2. 最小化公式值: 我们需要找到公式值的最小值,因此,我们需要比较每个计算出来的值,更新最小值。

代码解读:

import java.util.Arrays;
import java.util.List;

public class Main {

    public static int solution(int n, int m, int k, List<Integer> a, List<Integer> b) {
        // 初始化最小值为最大整数
        int minValue = Integer.MAX_VALUE;

        // 双重循环遍历a和b中的所有可能组合
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                int aMinusB = a.get(i) - b.get(j); // 计算 a[i] - b[j]

                // 计算平方差公式
                int value = Math.abs((aMinusB * aMinusB) - (k * k));

                // 如果找到更小的值,则更新最小值
                if (value < minValue) {
                    minValue = value;
                }
            }
        }

        return minValue; // 返回最终最小值
    }

    public static void main(String[] args) {
        // 测试用例 1
        List<Integer> a1 = Arrays.asList(5, 11, 4, 24, 3, 14, 16, 22, 4, 3, 5, 12, 12, 11, 12, 18);
        List<Integer> b1 = Arrays.asList(23, 16, 6, 20, 1, 10, 16, 17, 17, 1, 23);
        System.out.println("最终结果: " + solution(16, 11, 25, a1, b1)); // 应输出 104

        // 测试用例 2
        List<Integer> a2 = Arrays.asList(5, 3, 4, 1, 2);
        List<Integer> b2 = Arrays.asList(0, 6, 7, 9, 8);
        System.out.println("最终结果: " + solution(5, 5, 1, a2, b2)); // 应输出 0

        // 测试用例 3
        List<Integer> a3 = Arrays.asList(5, 3, 4, 1, 2);
        List<Integer> b3 = Arrays.asList(0, 6, 7, 9, 8);
        System.out.println("最终结果: " + solution(5, 5, 0, a3, b3)); // 应输出 1

        // 测试用例 4
        List<Integer> a4 = Arrays.asList(5, 3, 4, 1, 2);
        List<Integer> b4 = Arrays.asList(0, 6, 7, 9, 8, 11);
        System.out.println("最终结果: " + solution(5, 6, 3, a4, b4)); // 应输出 0
    }
}

代码说明:

  • 输入参数:
    • n: 数列 a 的长度。
    • m: 数列 b 的长度。
    • k: 给定的整数。
    • a: 整数数列 a
    • b: 整数数列 b
  • 主算法:
    1. 初始化最小值 minValueInteger.MAX_VALUE,这是为了确保在第一次计算时可以更新为一个有效的值。
    2. 使用两层嵌套的 for 循环遍历数列 ab 中的所有可能的 (a[i], b[j]) 对。
    3. 对每一对 (a[i], b[j]),计算公式: ∣(a[i]−b[j])2−k2∣\left| (a[i] - b[j])^2 - k^2 \right| 并通过 Math.abs 计算其绝对值。
    4. 更新 minValue,如果当前计算出的值比当前 minValue 小,则更新 minValue
    5. 最终返回最小的 minValue

复杂度分析:

  • 时间复杂度:O(n * m),因为我们需要遍历所有的 a[i]b[j],对于每一对组合计算公式的值。
  • 空间复杂度:O(1),我们只使用了常数空间来保存计算的结果。

例子解析:

  1. 测试用例 1:

    数列 a 长度为 16,b 长度为 11,k = 25。我们通过遍历每一对 (a[i], b[j]) 计算公式值,最终得到最小的结果 104

  2. 测试用例 2:

    数列 a = [5, 3, 4, 1, 2]b = [0, 6, 7, 9, 8]k = 1。我们发现,(a[0] - b[1])^2 - k^2 = 0,因此最小值为 0

  3. 测试用例 3:

    数列 a = [5, 3, 4, 1, 2]b = [0, 6, 7, 9, 8]k = 0。最小值为 1,即 (a[0] - b[2])^2 - k^2 = 1

  4. 测试用例 4:

    数列 a = [5, 3, 4, 1, 2]b = [0, 6, 7, 9, 8, 11]k = 3。最小值为 0

总结:

这个问题考察的是我们对循环嵌套的运用和对数学公式的理解。通过暴力遍历所有组合并计算其公式值,最后找到最小值。这是一个典型的组合优化问题,适合通过枚举所有可能的解来解决。