letcode33搜索旋转排序数组

题目规定,只能用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;
    }
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值