c++版本,好恶心的题,目前还没有找到最优解,速度比java的要慢很多
给定一个整数数组和一个整数 k, 你需要在数组里找到不同的 k-diff 数对。这里将 k-diff 数对定义为一个整数对 (i, j), 其中 i 和 j 都是数组中的数字,且两数之差的绝对值是 k.
输入: [3, 1, 4, 1, 5], k = 2
输出: 2
解释: 数组中有两个 2-diff 数对, (1, 3) 和 (3, 5)。
尽管数组中有两个1,但我们只应返回不同的数对的数量。
输入: [1, 3, 1, 5, 4], k = 0
输出: 1
解释: 数组中只有一个 0-diff 数对,(1, 1)
一,超恶心的暴力解法
先排序,直接选定i值,根据i,进行j的遍历,找到差值为k的值,同时count加1,注意的点:会出现重复的数值计算,
int findPairs(vector<int>& nums, int k) {
int len=nums.size();
int count=0;
sort(nums.begin(),nums.end());
for(int i=0;i<len;i++){
if(i!=0&&nums[i]==nums[i-1])
continue; //如果出现重复的值,只计算第一次出现的,
for(int j=i+1;j<len;j++){
if(abs(nums[j]-nums[i])==k){
count++;
break;//防止发生重复,如(1,3,3)k=2
}
}
}
return count;
}
二,利用排序+二分查找(双指针的,不容易理解,且速度半斤八两,也许是自己还没有找到最优的吧,真是头疼)
int findPairs(vector<int>& nums, int k) {
int len=nums.size();
int count=0;
sort(nums.begin(),nums.end());
for(int i=0;i<len;i++){
if(i!=0&&nums[i]==nums[i-1]){
continue;//如果发现当前值与前一个值相等,排除重复行为,结束本次循环,不在往下进行,重新本次for循环。
}
auto tmp=lower_bound(nums.begin()+i+1,nums.end(),k+nums[i]);
if(tmp==nums.end())
break;//如果查找失败,说明此刻数组中最大值比nums[i]+k小,因此无需再进行查找,结束整体循环。
break;
if(*tmp==k+nums[i]){
count++;
}
}
return count;
}
扩展:
1,auto函数
根据变量的初始值类型,自动为此变量选择匹配类型。在实际应用中不建议使用,一般都会直接表示该变量类型。比如此处tmp,真心不知道如何表示该类型,是vector?么好像不是滴,是个指针地址,感觉太菜了,。
2,lower_bound(begin,end,num):
从小到大
从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
**lower_bound( begin,end,num,greater() )**大–小
3,对于continue,break理解比较混乱,这次终于理解了,continue,break
4,对于一些变量的理解,
nums{1,3,4,6,8,9}
nums.begin()====> {1} /返回指向容器最开始位置数据的指针
nums.begin()+1====> {3} /下坐标加1,返回其指针
nums.end()-1====> {9} /返回指向容器最后一个数据单元+1的指针
tmp ===> i=0 k=3 时,tmp: {4},, *tmp = 4