力扣 1385、两个数组间的距离值(Java二分法解决)

题目

给你两个整数数组 arr1 , arr2 和一个整数 d ,请你返回两个数组之间的 距离值 。

「距离值」 定义为符合此距离要求的元素数目:对于元素 arr1[i] ,不存在任何元素 arr2[j] 满足 |arr1[i]-arr2[j]| <= d 。

示例 1:
输入:arr1 = [4,5,8], arr2 = [10,9,1,8], d = 2
输出:2
解释:

对于 arr1[0]=4 我们有:
|4-10|=6 > d=2
|4-9|=5 > d=2
|4-1|=3 > d=2
|4-8|=4 > d=2
所以 arr1[0]=4 符合距离要求

对于 arr1[1]=5 我们有:
|5-10|=5 > d=2
|5-9|=4 > d=2
|5-1|=4 > d=2
|5-8|=3 > d=2
所以 arr1[1]=5 也符合距离要求

对于 arr1[2]=8 我们有:
|8-10|=2 <= d=2
|8-9|=1 <= d=2
|8-1|=7 > d=2
|8-8|=0 <= d=2
存在距离小于等于 2 的情况,不符合距离要求

故而只有 arr1[0]=4 和 arr1[1]=5 两个符合距离要求,距离值为 2

1 <= arr1.length, arr2.length <= 500
-10^3 <= arr1[i], arr2[j] <= 10^3
0 <= d <= 100

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/find-the-distance-value-between-two-arrays
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

博主的话

这个题虽说是简单题,也确实使用暴力解法的话,运行结果是很客观的,并且暴力解法的执行时间是比二分解法的执行时间要短的。
但是这个题我们去尽量换思维的方式去解题,在我们平时做练习的时候,不能为解题而且做题,重要的是思维。
也是因为这个题用二分的话,不是很好理解,所以博主也就分享了这道题。

暴力解法

暴力解法就是两个for循环嵌套,对两个数组进行遍历,一个一个的查找找出结果来。

暴力这就不对代码进行具体解释了,不难很简单

class Solution {
    
    
    public int findTheDistanceValue(int[] arr1, int[] arr2, int d) {
    
    
        int len1 = arr1.length, len2 = arr2.length;//获得两个数组的长度
        int res = 0;//最后返回的值
        for (int i = 0; i < len1; i++) {
    
    
            res++;//每次开始对数组1里面的数进行判断的时候先对结果加1
            for (int j = 0; j < len2; j++) {
    
    
            	//对第二个数组进行发现只要出现一例不合格的,就减去前面加的一个,然后就可以终止对数组2的遍历循环了。
                if (Math.abs(arr1[i] - arr2[j]) <= d) {
    
    
                    res--;
                    break;
                }
            }
        }
        return res;
    }
}

二分法解决

在使用二分法的时候,我们认为每次是从数组1当中拿数据,然后和数组2中的元素进行比较。

因为使用了二分法,所以我们对数组2进行排序,又因为在这个当中,数组中的元素大小可以为负数,所以单纯的通过思考是及其难想明白的。

在这里我们借用画图来思考这个问题。
在这里插入图片描述

相信通过这个图去理解这个题就不会很困难。

下来看代码:

class Solution {
    
    
    public int findTheDistanceValue(int[] arr1, int[] arr2, int d) {
    
    
        Arrays.sort(arr2);//对数组2进行从小到大的排序
        int ans = 0;//最终结果返回
        int len1 = arr1.length, len2 = arr2.length;
        for (int i = 0; i < len1; i++) {
    
    
            int min = arr1[i] - d;//获得当前arr1数组中元素结合d区间的最小值
            int max = arr1[i] + d;//获得当前arr1数组中元素结合d区间的最大值

            //若判断出arr2数组中的最大元素小于区间最小值,数组最小值大于区间最大值,直接给予通过
            if (arr2[0] > max || arr2[len2 - 1] < min) {
    
    
                ans++;
                continue;
            }

            //下来就是标准的二分查找
            int left = 0, right = len2 - 1;
            boolean res = false;
            while (left <= right) {
    
    
                int mid = left + (right - left) / 2;
                //当中间值在区间内的时候,就可以结束循环了
                if (arr2[mid] >= min && arr2[mid] <= max) {
    
    
                    res = true;
                    break;
                } else if (arr2[mid] < min) {
    
    
                    left = mid + 1;
                } else if (arr2[mid] > max) {
    
    
                    right = mid - 1;
                }
            }
            //最后再决定对当前这个值是否合格
            if (!res) {
    
    
                ans++;
            }
        }
        return ans;
    }
}

如还有什么疑问,欢迎在评论区讨论。

猜你喜欢

转载自blog.csdn.net/weixin_45970271/article/details/125256939