0x01.问题
给你两个整数数组
arr1
,arr2
和一个整数d
,请你返回两个数组之间的 距离值
「距离值」 定义为符合此描述的元素数目:对于元素arr1[i]
,不存在任何元素arr2[j]
满足
|arr1[i]-arr2[j]| <= d
。
输入示例:arr1 = [4,5,8], arr2 = [10,9,1,8], d = 2
输出示例:2
提示:1 <= arr1.length, arr2.length <= 500
-10^3 <= arr1[i], arr2[j] <= 10^3
0 <= d <= 100
C++函数形式: int findTheDistanceValue(vector<int>& arr1, vector<int>& arr2, int d)
0x02.简要分析
读题,注意题目中的距离值实际指的是满足指定条件的元素个数,而且条件是不存在。
暴力枚举,肯定可以做到,时间复杂度为O(N^2)
,显然不是最好的方法,这里我们采用二分查找的方法。
我们发现题目的核心在于那个绝对值等式,只需要那个绝对值的最小值都大于d
,肯定是满足的,所以我们其实只要找到那个绝对值的最小值就行了,不需要遍历整个数组。
两个数越相近,绝对值越小,所以我们可以找到最相近的那个数,于是我们的二分思路就来了。
首先对数组进行排序,排序后,用二分法找到刚好比arr1
中大一点的数,假设下标为b
然后我们看arr2[b]-a
,arr2[b-1]-1
,arr2[b+1]-1
,这三个数是否满足条件就行了,因为绝对值的最小值一定在这三个中取到,当然,还要额外注意找的这个数是否是边界下标。
0x03.解决代码–二分法(O(N*logN))
class Solution {
public:
int biSh(int left,int right,vector<int>& arr,int target){
if(left>=right) return left;
int mid=(left+right)/2;
if(arr[mid]==target) return mid;
return arr[mid]<target?biSh(mid+1,right,arr,target):biSh(left,mid,arr,target);
}
int findTheDistanceValue(vector<int>& arr1, vector<int>& arr2, int d) {
int ans=0;
int n=arr2.size()-1;
sort(arr2.begin(),arr2.end());
for(int a:arr1){
int b=biSh(0,n,arr2,a);
if(abs(arr2[b]-a)<=d) continue;
else if(abs(arr2[max(0,b-1)]-a)<=d) continue;
else if(abs(arr2[min(n,b+1)]-a)<=d) continue;
ans++;
}
return ans;
}
};
ATFWUS --Writing By 2020–03–23