LeetCode-33 search-in-rotated-sorted-array 搜索旋转排序数组

题目链接

https://leetcode-cn.com/problems/search-in-rotated-sorted-array/

前排提示

《剑指offer》题,二分搜索找特殊条件,感觉书上描述的很简单,(可能之前做过所以觉得简单点。。)

题意

        对于一个升序排序的数组,从某个位置截断,然后直接拼在后面。看题目给的例子,还是比较直白的。

题解

        其实题本身不难,做了一些中等难度的题,其实大部分都没啥难度,简单题反而有一些比较骚的。中等题很多都坑在略考验码速,有一个大数乘法、螺旋数组的模拟等等,这个题也一样,撸一堆代码,出一点错就很蛋疼。

        看评论有人吐槽直接遍历也能搜出来答案= =因为要求时间复杂度是O(logn),并且是已经升序排序的数组了,只是中间截断了而已。那么反过来,如果从截断点开始分成两个数组,那么对于单个数组就可以使用二分搜索了,而二分搜索恰是O(logn)的时间复杂度。

        问题就是如何找到截断点。很明显,如果没有截断点的话,直接升序,对于i而言:arr[i-1] < arr[i] < arr[i+1]这个等式是恒成立的,题也说了不存在重复。如果存在i:arr[i - 1] > arr[i] || arr[i] > arr[i+1],那么i就是截断点,并且属于后半数组。所以,找到截断点就是比较重要了。for循环遍历就有点蛋疼了,仍然使用二分,可以先找截断点。找到以后就将数组分成左右两部分,分别使用二分搜索即可。

        这个题情况非常多,所以剪枝能写很多。例如分开二分搜索的时候,如果第一个数组就搜到答案了,那么第二组就可以不搜索了。如果在搜截断点的时候就找到答案,那么就可以直接结束了。等等。

        另外我的代码是忽略了数组元素小于3的数据,这些单独拿出来计算了。主要是交的时候发现WA了,所以就拿出来单独算。可能是搜截断点的时候,数组元素是2的时候各种越界吧,懒得写了,所以就直接判断了特殊情况= =。

Java 代码

class Solution {
    public static int flag;
    public static int len;
    public static int ans;

    public static void search(int left,int right,int[] nums){
        if(left == right) return;
        int mid = (left+right)/2;
        if(mid == 0){
            if(nums[mid] > nums[mid+1]){
                flag = mid;
                return;
            }
        }else{
            if(mid == len-1){
                if(nums[mid] < nums[mid-1]){
                    flag = mid;
                    return;
                }
            }else{
                if(nums[mid] > nums[mid+1] || nums[mid] < nums[mid-1]){
                    flag = mid;
                    return;
                }
            }
        }
        search(left,mid,nums);
        if(flag != -1) return;
        search(mid+1,right,nums);
    }

    public static void brain(int left,int right,int[] nums,int target){
        if(left == right){
            if(target == nums[left]){
                ans = left;
            }
            return;
        }
        int mid = (left+right)/2;
        if(target == nums[mid]){
            ans = mid;
            return;
        }
        if(target > nums[mid]){
            brain(mid+1,right,nums,target);
        }else{
            brain(left,mid,nums,target);
        }
    }

    public int search(int[] nums, int target) {
        flag = -1;
        ans = -1;
        len = nums.length;
        if(len == 0) return -1;
        if(len == 1){
            if(target == nums[0]) return 0;
            return -1;
        }
        if(len == 2){
            for(int i = 0;i < 2;i++){
                if(target == nums[i]) return i;
            }
            return -1;
        }
        search(0,len-1,nums);
        if(flag == -1){
            brain(0,len-1,nums,target);
            return ans;
        }
        if(nums[flag] == target) return flag;
        brain(0,flag,nums,target);
        if(ans != -1) return ans;
        brain(flag+1,len-1,nums,target);
        return ans;
    }
}

 

你可能感兴趣的:(LeetCode,leetcode-腾讯,2018,秋招精选(50,题))