LeetCode Easy: 33. Search in Rotated Sorted Array

一、题目

Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.

(i.e., [0,1,2,4,5,6,7] might become [4,5,6,7,0,1,2]).

You are given a target value to search. If found in the array return its index, otherwise return -1.

You may assume no duplicate exists in the array.

Your algorithm's runtime complexity must be in the order of O(log n).

Example 1:

Input: nums = [4,5,6,7,0,1,2], target = 0
Output: 4

Example 2:

Input: nums = [4,5,6,7,0,1,2], target = 3
Output: -1

题目大意:给定一个旋转数组和一个 target,返回 target 所在的下标。

二、思路

思路一、因为旋转数组有个点破坏了数组的有序性,但是有且仅有这一个点,此点之前是有序的,此点之后也是有序的,所以可以先找到这个转折点,然后两边就能顺理成章地使用二分法进行搜索了。下边的代码使用的即是此思路。

思路二、如果是正常的排好序的数组,那么使用二分法就能很快地找到 target 所在的下标,但是给定的可能是一个旋转数组,不能直接使用二分法,但是旋转数组虽然不能直接使用二分法,但是其部分数据可以使用,如果我们把旋转数组分成两个部分,那么其中某一部分肯定能使用二分法,剩下的那部分还是一个旋转数组,可以继续二分,可以使用迭代循环或者递归。这是一个思路。

三、代码

#coding:utf-8
class Solution:
    def search(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        if len(nums) <= 0:
            return -1
        pivot = self.FindPivot(nums)
        if pivot == -1:
            return self.Search(nums,0,len(nums)-1,target)
        if nums[pivot] == target:
            return pivot
        if nums[0] <= target:
            return self.Search(nums,0,pivot,target)
        else:
            return self.Search(nums,pivot+1,len(nums)-1,target)

    def Search(self,nums,start,end,target):
        if start > end:
            return -1
        while start <= end:
            mid = (start + end)//2
            if nums[mid] == target:
                print(mid)
                return mid
            elif nums[mid] > target:
                end = mid -1
            else:
                start = mid + 1
        print(-1)
        return -1

    def FindPivot(self,nums):
        start = 0;end = len(nums)-1
        if nums[end] > nums[start]: # the list sorted
            return -1
        # search rotated list
        while(start <= end):
            mid = (start + end)//2
            if nums[mid] > nums[start]:  # the Pivot is in [mid,end]
                start = mid
            elif nums[mid] < nums[start]:
                end = mid
            else:
                return mid

if __name__ == '__main__':
    ss = Solution()
    nums = [3,1]
    ss.search(nums,1)

还有一种更紧凑的代码,博客:https://blog.csdn.net/aliceyangxi1987/article/details/50557496

class Solution:
    def search(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        start = 0
        end = len(nums) - 1
        while start <= end:
            mid = (start + end) // 2
            if nums[mid] == target:
                print(mid)
                return mid
            if nums[mid] >= nums[start]:  # 当nums[mid]属于左边升序序列时
                if target >= nums[start] and target < nums[mid]:
                    end = mid - 1
                else:
                    start = mid + 1
            if nums[mid] < nums[end]:  # 当nums[mid]属于右边升序序列时
                if target > nums[mid] and target <= nums[end]:
                    start = mid + 1
                else:
                    end = mid - 1
        return -1

  

参考博客:https://blog.csdn.net/sunnyyoona/article/details/18313497

既然无论如何时间都会过去,为什么不选择做些有意义的事情呢
原文地址:https://www.cnblogs.com/xiaodongsuibi/p/8973159.html