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

93 阅读3分钟

数列差异的最小化这道题属于二分查找的题库,题目大意是在两个数组a、b中找出一组组合a[i]和b[j]从而使的公式|(a[i]-b[j])^2-k^2|的值最小(k是固定的)输出最小值即可。 解题思路: 分析:通过上述公式分析过后可知我们如果想要找到|(a[i]-b[j])^2-k^2|公式的最小值其中a[i]、b[j]是变量k是不变量而且公式结果的大小范围一定是大于等于0的所以最小值就是0,如果想要使公式值最小那么我们只需要让(a[i]-b[j])^2趋近于k^2即可如果等于k^2那么就输出最小值0; 1、创建一个新的数组将所有a[i]-b[j]的绝对值组合存入其中 2、利用二分查找去新的数组中查找k^2 3、判断若在数组中查找到有元素的值等于k^2则直接输出0即公式的最小值为0 4、如果未查找到数组中有元素的值等于k^2就要分情况来处理了 5、边界值处理,当二分查找的指针移动到数组边界时因为判定条件是当左指针越过右指针时循环结束所以为了避免空指针情况的发生我们在移动指针的代码块中增加一个判断如果right==-1的时候直接输出新数组中下标为0的元素至公式中返回如果是left==新数组的长度的话直接输出新数组中末位元素至公式中返回即可 6、一般情况则是在一个while死循环中利用二分查找的特点在左右指针移动的代码块中分别增加判断输出公式的最小值 新数组中元素的选择的规定则是找不到k^2时那就在left>right时取包含k^2的两个元素区间判断这两个元素哪个输出至公式中使公式得到最小值即可。 总而言之对于本题我的解法是 创建新数组+二分查找

package com.zx;

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

public class Code2 {
    public static int solution(int n, int m, int k, List<Integer> a, List<Integer> b) {
        //定义一个数组存储(a[i]-b[i])^2的各种情况然后排序
        int[] c = new int[n * m];
        int index = 0;
        for (int i = 0; i < a.size(); i++) {
            for (int j = 0; j < b.size(); j++) {
                c[index] = (a.get(i) - b.get(j)) * (a.get(i) - b.get(j));
                index++;
            }
        }
        c=Arrays.stream(c).distinct().toArray();
        Arrays.sort(c);

        //二分查找K^2如果找到则直接返回0否则找其相邻的数组元素进行公式运算后比较大小取最小的数
        int left = 0;
        int right = c.length - 1;
        int middle = (left + right) / 2;
        while (true) {
            if (c[middle] == k * k) {
                return 0;
            } else if (c[middle] > k * k) {
                right = middle - 1;
                middle = (left + right) / 2;
                if (left > right) {
                    if (right == -1) return Math.abs(c[0] - k * k);
                    return Math.min(Math.abs(c[right] - k * k), Math.abs(c[right + 1] - k * k));
                }
            } else {
                left = middle + 1;
                middle = (left + right) / 2;
                if (left > right) {
                    if (left == c.length) return Math.abs(c[c.length-1] - k * k);
                    return Math.min(Math.abs(c[left] - k * k), Math.abs(c[left - 1] - k * k));
                }
            }

        }
    }

    public static void main(String[] args) {
        // You can add more test cases here
        // case 1
//        List<Integer> a1 = Arrays.asList(5, 3, 4, 1, 2);
//        List<Integer> b1 = Arrays.asList(0, 6, 7, 9, 8);
//        System.out.println(solution(5, 5, 1, a1, b1) == 0);
//
//        // case 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, 0, a2, b2) == 1);
//
//        // case 3
//        List<Integer> a3 = Arrays.asList(5, 3, 4, 1, 2);
//        List<Integer> b3 = Arrays.asList(0, 6, 7, 9, 8, 11);
//        System.out.println(solution(5, 6, 3, a3, b3) == 0);

        //case 4
        List<Integer> a4 = Arrays.asList(5,11,4,24,3,14,16,22,4,3,5,12,12,11,12,18);
        List<Integer> b4 = Arrays.asList(23,16,6,20,1,10,16,17,17,1,23);
        System.out.println(solution(16, 11, 25, a4, b4) == 0);

    }
}

本题在豆包刷题中还暂未通过目前来说应该是测试用例出了一点小问题已反馈但不影响对于解题思路的一个思考且我们还可以借助豆包AI助手帮我们整理思路、检查代码以此来提升自己的思维能力以及代码输出能力。