30-Day Leetcoding Challenge Day19

本题主要用二分法的思想。因为题目要求时间复杂度为O(logn)。

1.首先用二分法找到旋转点,将数组分为两个递增子序列,再分别对两个子数组用二分法找到目标值。

2.再传统的二分法基础上多加一次判断,判断当前序列是否为递增序列。

 

JAVA

class Solution {
    int []nums;
    int target;
    public int rotated(int left, int right){
        if(nums[left] < nums[right])return 0;
        while(left <= right){
            int pivot = (left+right)/2;
            if(nums[pivot] > nums[pivot+1])return pivot+1;
            if(nums[left] > nums[pivot]) right = pivot-1;
            else left = pivot+1;
        }
        return 0;//bug要写返回值
    }
    public int search(int left, int right){
        while(left <= right){
            int mid = (left+right)/2;
            if(nums[mid] == target) return mid;
            else{
                if(nums[mid] > target)right = mid-1;
                else left = mid+1;
            }
        }
        return -1;
    }
    public int search(int[] nums, int target) {
        this.nums = nums;
        this.target = target;
        int n = nums.length;
        if(n == 0)return -1;
        if(n == 1){
            if(nums[0] == target)return 0;
            else return -1;
        }
        int ro_index = rotated(0, n-1);
        if(ro_index == 0)return search(0, n-1);
        if(nums[0] > target)return search(ro_index, n-1);
        else return search(0, ro_index-1);
    }
}

 

class Solution {
    public int search(int[] nums, int target) {
        int n = nums.length;
        int left = 0;
        int right = n-1;
        while(left <= right){
            int mid = (left+right)/2;
            if(nums[mid] == target)return mid;
            if(nums[mid] >= nums[left]){
                if(nums[mid] >= target && nums[left] <= target){
                    right =  mid-1;
                }
                else left = mid+1;
            }
            else{
                if(nums[mid] <= target && nums[right] >= target){
                    left = mid+1;
                }
                else right = mid-1;
            }
        }
        return -1;
    }
}

 

Python3

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        def rotated(left, right):
            if nums[left] < nums[right]:
                return 0
            while left <= right:
                pivot = (left+right)//2
                if nums[pivot] > nums[pivot+1]:#二分法判定旋转点
                    return pivot+1 
                else:
                    if nums[pivot] >= nums[left]:
                        left = pivot+1
                    else:
                        right = pivot-1
        def search(left, right):
            while left <= right:
                mid = (left+right)//2
                if nums[mid] == target: #二分法判定找到目标值
                    return mid
                else:
                    if nums[mid] > target:
                        right = mid-1
                    else:
                        left = mid+1
            return -1
        
        n = len(nums)
        if n == 0:
            return -1
        if n == 1:
            return 0 if nums[0] == target else -1
        ro_index = rotated(0, n-1) #找到旋转点
        if ro_index == 0: #数组有序
            return search(0, n-1)
        if target < nums[0]: #在右边有序数组中
            return search(ro_index, n-1)
        else:              #在左边有序数组中
            return search(0, ro_index-1)

 

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        n = len(nums)
        left = 0
        right = n-1
        while left <= right:
            mid = (left+right)//2
            if nums[mid] == target:
                return mid
            if nums[mid] >= nums[left]:
                if nums[left] <= target <= nums[mid]:
                    right = mid-1
                else:
                    left = mid+1
            else:
                if nums[mid] <= target <= nums[right]:
                    left = mid+1
                else:
                    right = mid-1
        return -1

 

posted @ 2020-04-29 18:19  yawenw  阅读(127)  评论(0编辑  收藏  举报