81. 搜索旋转排序数组 II

题目链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

81. 搜索旋转排序数组 II_第1张图片解题思路:

解法一:直接从前往后搜索,时间复杂度O(n)

AC代码:

class Solution {
    public boolean search(int[] nums, int target) {
        for (int num : nums) {
            if (num == target) {
                return true;
            }
        }
        return false;
    }
}

 解法二:二分查找

因为有序数组nums预先是在k位置进行了旋转,那么对于任意一个下标 i ,会将nums分为左半部分和右半部分,那么左半部分和右半部分一定是一个有序,一个无序的。所以如果能够确定哪一部分有序,那么就可以在有序的那一部分使用二分查找。

确定那一部分有序:对于下标 left ,mid,right,将nums分为两部分nums[left,mid],nums[mid,right]

  1. 如果nums[left] < nums[mid],说明左半部分有序
  2. 否则,即nums[mid]
  3. 但是有种特殊情况,判断不出哪一部分是否有序,那就是nums[left] == nums[mid]这种情况,比如 [ 1,0,1,1,1 ],当 left =0,mid = 2时,此时nums[left] == nums[mid],此时如果出现这种情况,就令 left++,将最左边重复的那一项去掉,直到不会出现nums[left] != nums[mid],这个时候,就可以判断出那一部分有序,之后就一直在有序的那一部分进行二分查找

AC代码:

class Solution {
    public boolean search(int[] nums, int target) {
        int left = 0;
        int right = nums.length;
        while (left < right) {
            int mid = left + (right - left) / 2;
            if (nums[mid] == target) {
                return true;
            }
            
            //此时判断不出那一部分有序,令left++,去除重复项
            if (nums[left] == nums[mid]) {
                left++;
                continue;
            }
            
            if (nums[left] < nums[mid]) {//左半部分有序
                //target在左部分中
                if (nums[left] <= target && nums[mid] > target) {
                    right = mid;
                }else {
                    //在右半部分中
                    left=mid+1;
                }
            }else {//右半部分有序
                //在右半部分中
                if (nums[mid]=target){
                    left = mid+1;
                }else {
                    //在作伴部分中
                    right =mid;
                }
            }
        }
        return false;
    }
}

81. 搜索旋转排序数组 II_第2张图片

 不过这种解法在最坏情况下的时间复杂度和方法一相同,都为O(n)

 

你可能感兴趣的:(LeetCode_Java版,二分,leetcode,算法,职场和发展)