简单二分查找,需要注意的是溢出问题
class Solution {
public:
bool isPerfectSquare(int num) {
int p=1,q=num/2;
if(num==1){
return 1;
}
while(p<=q){
long long int mid=(q+p)/2;
if(mid*mid==num){
return 1;
}
else if(mid*mid>num){
q=mid-1;
}
else{
p=mid+1;
}
}
return 0;
}
};
一眼没看出来用二分怎么写,看了下数据量给得小,于是用暴力试试,过了。
class Solution {
public:
int findTheDistanceValue(vector<int>& arr1, vector<int>& arr2, int d) {
int ans=0;
for(int i=0;i<arr1.size();i++){
int flag=1;
for(int j=0;j<arr2.size();j++){
if(abs(arr1[i]-arr2[j])<=d){
flag=0;
break;
}
}
if(flag){
ans++;
}
}
return ans;
}
};
看了下答案才知道怎样用二分,不过答案描述的并不清晰。
答案的意思是:假设arr1中当前元素为x,那么要在arr2中寻找两个最接近x的数y1,y2,且y1<x<y2。那么如果x-y1>d和y2-x>d都满足的话,对于arr2中其他元素也满足与x距离大于d,此时x就符合题意了。
另外,还在答案中发现了个没见过的函数 lower_bound( ),于是去了解了一下。
在从小到大排序的数组内有:
lower_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到就返回该数字的地址,未找到则返回end。通过返回的地址减去起始地址begin,可得到找到数字在数组中的下标。
upper_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
在从大到小排列的数组则相反。
最后放上代码
class Solution {
public:
int findTheDistanceValue(vector<int>& arr1, vector<int>& arr2, int d) {
int ans=0;
sort(arr2.begin(),arr2.end());
for(int i=0;i<arr1.size();i++){
int n=0;
int p=lower_bound(arr2.begin(),arr2.end(),arr1[i])-arr2.begin();
if(p<arr2.size()&&p-1>=0){
if(arr2[p]-arr1[i]>d&&arr1[i]-arr2[p-1]>d){
n=1;
}
}
else if(p==arr2.size()){
if(arr1[i]-arr2[arr2.size()-1]>d){
n=1;
}
}
else if(p==0){
if(arr2[0]-arr1[i]>d){
n=1;
}
}
if(n){
ans++;
}
}
return ans;
}
};