题目规定,只能用log(n)复杂度的算法。
我特意找的二分专题,但是不难发现这题是二分。
思路:要么左边是一只递增的,要么右边是一直递增的。
然后先分为这两种情况,每种情况,还可以再细分,具体怎么细分,代码见。
class Solution {
public:
int l, r;
int judge(vector<int>& nums,int target, int mid){//-1左移,1右移,0找到
if(nums[mid] < nums[l]){
if(target < nums[mid]) return -1;
else if(target > nums[mid]){
if(nums[r] >= target) return 1;
else if(nums[r] < target) return -1;
}
else return 0;
}
else if(nums[mid] > nums[l]){
if(target > nums[mid])
return 1;
else if(target < nums[mid]){
if(nums[l] <= target) return -1;
else if(nums[r] > target)return 1;
}
else return 0;
}
return 3;
}
int search(vector<int>& nums, int target) {
l=0, r=nums.size()-1;
if(r==0){
if(nums[l] == target) return 0;
else return -1;
}
while(l<=r){
int mid=l+(r-l)/2;
int j=judge(nums, target, mid);
if(j == -1)
r = mid-1;
else if(j == 1)
l = mid+1;
else if(j==0)
return mid;
else {
if(nums[l]==target) return l;
if(nums[r]==target) return r;
return -1;
}
}
return -1;
}
};
随后我尝试交了一发c语言On的算法,结果竟然比logn的时间快!!数据太少了。
这里我还发现了一个bug,当在上面运行一下示例之后在提交,时间永远是0ms。
后来觉得自己代码是不是有点长。看了下评论,发现一个大佬写的,绝了。思路跟我的一样,但是把所有情况罗列之后,很巧妙的使用了异或把各个情况整合在一起,最后就很短。贴一下代码。
class Solution {
public:
int search(vector<int>& nums, int target) {
int lo = 0, hi = nums.size() - 1;
while (lo < hi) {
int mid = (lo + hi) / 2;
if ((nums[0] > target) ^ (nums[0] > nums[mid]) ^ (target > nums[mid]))
lo = mid + 1;
else
hi = mid;
}
return lo == hi && nums[lo] == target ? lo : -1;
}
};

被折叠的 条评论
为什么被折叠?



