LeetCode(Binary Search)1385. Find the Distance Value Between Two Arrays

给定两个整数数组arr1和arr2以及整数d,返回两个数组间的距离值,即arr1中有多少个元素与arr2中任何元素的绝对差值大于d。文章提供了三种解题思路:遍历比较,排序+二分查找,以及使用哈希表。并给出了相应的Java代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.问题

Given two integer arrays arr1 and arr2, and the integer d, return the distance value between the two arrays.

The distance value is defined as the number of elements arr1[i] such that there is not any element arr2[j] where |arr1[i]-arr2[j]| <= d.

Example 1:

Input: arr1 = [4,5,8], arr2 = [10,9,1,8], d = 2
Output: 2
Explanation:
For arr1[0]=4 we have:
|4-10|=6 > d=2
|4-9|=5 > d=2
|4-1|=3 > d=2
|4-8|=4 > d=2
For arr1[1]=5 we have:
|5-10|=5 > d=2
|5-9|=4 > d=2
|5-1|=4 > d=2
|5-8|=3 > d=2
For arr1[2]=8 we have:
|8-10|=2 <= d=2
|8-9|=1 <= d=2
|8-1|=7 > d=2
|8-8|=0 <= d=2

Example 2:

Input: arr1 = [1,4,2,3], arr2 = [-4,-3,6,10,20,30], d = 3
Output: 2

Example 3:

Input: arr1 = [2,1,100,3], arr2 = [-5,-2,10,-3,7], d = 6
Output: 1

Constraints:

  • 1 <= arr1.length, arr2.length <= 500
  • -1000 <= arr1[i], arr2[j] <= 1000
  • 0 <= d <= 100

2. 解题思路

方法1:

1.遍历arr1中的每个元素,对于每个元素,都要遍历arr2中的每个元素。
2.计算两个元素之间的绝对差值,如果差值大于d,则将计数器加1。
3.最终返回计数器的值,它表示arr1中有多少个元素与arr2中的每个元素的绝对差值都大于d。
注意事项:
在第二步中,我们应该使用绝对差值而不是简单的减法运算来计算两个元素之间的距离。
在第三步中,我们应该将计数器增加的条件更改为差值大于d,而不是小于等于d。

方法2:

排序 + 二分查找
首先,我们将arr2中的所有元素进行排序,然后遍历arr1中的每个元素,并使用二分查找来查找在arr2中距离当前元素最近的元素。如果最近的元素的绝对差值大于d,则将计数器加1。时间复杂度为O(nlogn)。

方法3:

使用哈希表来存储arr2中的所有元素,并遍历arr1中的每个元素。对于arr1中的每个元素,我们可以使用哈希表来查找与其距离小于等于d的元素。时间复杂度为O(n)。

3. 代码

代码1:

class Solution {
    public int findTheDistanceValue(int[] arr1, int[] arr2, int d) {
        int count = 0; // 初始化计数器
        for(int i = 0; i < arr1.length; i++){ // 遍历arr1中的每个元素
            boolean flag = true; // 初始化flag为true
            for(int j = 0; j < arr2.length; j++){ // 遍历arr2中的每个元素
                if(Math.abs(arr1[i] - arr2[j]) <= d){ // 如果两个元素的距离小于等于d
                    flag = false; // 将flag设置为false
                    break; // 退出arr2的循环
                }
            }
            if(flag){ // 如果flag仍为true
                count++; // 将计数器增加1
            }
        }
        return count; // 返回计数器的值
    }
}

增加了一个boolean类型的flag来表示arr1中的当前元素是否与任何一个arr2中的元素距离小于等于d。如果存在这样的元素,则将flag设置为false,并退出arr2的循环。如果没有这样的元素,则计数器增加1。最后返回计数器的值,它表示符合条件的元素的数量。

代码2:

class Solution {
    public int findTheDistanceValue(int[] arr1, int[] arr2, int d) {
        Arrays.sort(arr2); // 对arr2中的元素进行排序
        int count = 0;
        for(int i = 0; i < arr1.length; i++){ // 遍历arr1中的每个元素
            int index = Arrays.binarySearch(arr2, arr1[i]); // 使用二分查找来查找最近的元素
            if(index < 0){ // 如果找不到元素,则将其插入到正确的位置
                index = -(index + 1);
            }
            if((index == 0 || arr1[i] - arr2[index - 1] > d) && (index == arr2.length || arr2[index] - arr1[i] > d)){
                // 如果最近的元素的绝对差值大于d,则将计数器加1
                count++;
            }
        }
        return count; // 返回计数器的值
    }
}

使用了排序和二分查找来优化暴力解法,代码中的注释已经解释了每一步所做的事情,主要思路是遍历arr1中的每个元素,然后使用二分查找来查找arr2中与其距离小于等于d的元素,如果找到了这样的元素,则将计数器加1。最后,返回计数器的值作为答案。

class Solution {
    public int findTheDistanceValue(int[] arr1, int[] arr2, int d) {
        int distance = 0; // 初始化距离值
        
        Arrays.sort(arr2); // 对arr2中的元素进行排序
        
        for (int num1 : arr1) { // 遍历arr1中的每个元素
            // 使用二分查找来查找与当前元素距离小于等于d的元素
            if (Arrays.binarySearch(arr2, num1 - d) == Arrays.binarySearch(arr2, num1 + d)) {
                distance++; // 如果存在这样的元素,则将计数器加1
            }
        }
        
        return distance; // 返回计数器的值
    }
}

代码3:

class Solution {
    public int findTheDistanceValue(int[] arr1, int[] arr2, int d) {
        Set<Integer> set = new HashSet<>();
        for(int num : arr2){ // 将arr2中的所有元素添加到哈希表中
            set.add(num);
        }
        int count = 0;
        for(int num : arr1){ // 遍历arr1中的每个元素
            boolean flag = true;
            for(int i = num - d; i <= num + d; i++){ // 查找距离当前元素小于等于d的元素
                if(set.contains(i)){
                    flag = false;
                    break;
                }
            }
            if(flag){ // 如果不存在这样的元素,则将计数器加1
                count++;
            }
        }
        return count; // 返回计数器的值
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值