一看非递减排序,两数之和是target,啪的一下双指针就出来了,很快啊
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
int p=0,q=numbers.size()-1;
vector<int> ans;
int mm=numbers[p]+numbers[q];
while(p<q){
if(mm<target){
mm=numbers[++p]+numbers[q];
}
else if(mm>target){
mm=numbers[p]+numbers[--q];
}
else{
ans.push_back(p+1);
ans.push_back(q+1);
break;
}
}
return ans;
}
};
做完才发现不对啊,我不是来学二分的吗,怎么用起双指针了。
想想二分做法,找两个数之和等于target好像不太好找,不如先确定一个数x,然后另一个数就是target-x,可以用二分在剩下的数组里找,算一下复杂度O(nlogn),还不如双指针呢,懒得写了,直接下一题。
将所给数组排序后,如果x是特征值,令n为数组长度,则有:nums[n-x]>=x&&nums[n-x-1]<x
如果这个条件满足,就可认定x为特征值返回即可,然后就是二分的范围,数组的元素都是非负的,所以下界可以设为0,而且x肯定不大于最大的元素,所以上界可以说数组中最大的元素。接下来二分查找x就行了,不过要注意边界判断防止越界。
class Solution {
public:
int specialArray(vector<int>& nums) {
sort(nums.begin(),nums.end());
int n=nums.size();
for(int x=1;x<=n;x++){
if(x!=n&&nums[n-x]>=x&&nums[n-x-1]<x||x==n&&nums[0]>=x){
return x;
}
}
return -1;
}
};
懒得用二分写了,直接暴力run了