leetcode —— 33. 搜索旋转排序数组

假设按照升序排序的数组在预先未知的某个点上进行了旋转。

( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。

搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。

你可以假设数组中不存在重复的元素。

你的算法时间复杂度必须是 O(log n) 级别。

示例 1:

输入: nums = [4,5,6,7,0,1,2], target = 0
输出: 4

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/search-in-rotated-sorted-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
————————————————
解题思路:
(1)首先用二分查找,找到数组中最小值的索引位置。
(2)找到最小值的索引位置之后,通过二分查找找到相同值所在的位置。

其Python代码如下:

class Solution:
    def search(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        def find_rotate_index(left, right):  # 找到最小值所在的位置
            if nums[left] < nums[right]:  # 如果begin值小于end值,则数组是有序的,直接返回0,也就是开始值是最小值
                return 0
            
            while left <= right:  # 通过二分查找,找到中间值
                pivot = (left + right) // 2
                if nums[pivot] > nums[pivot + 1]:  # 如果中间值的下一个值小于中间值,则最小值为中间值的下一个值
                    return pivot + 1
                else:
                    if nums[pivot] < nums[left]: # 如果中间值小于开始值,则最小值在左边
                        right = pivot - 1
                    else:
                        left = pivot + 1
                
        def search(left, right):  # 寻找是否有匹配的值
            """
            Binary search
            """
            while left <= right:
                pivot = (left + right) // 2
                if nums[pivot] == target:  # 如果值相同,则返回索引位置
                    return pivot
                else:
                    if target < nums[pivot]:  # 如果target值大于中值,则取中值之前的部分
                        right = pivot - 1
                    else:  # 如果target值小于中值,则取中值之后的部分
                        left = pivot + 1
            return -1
        
        n = len(nums)   # 计算数组长度
        
        if n == 0:  # 如果数组为空,则返回-1
            return -1
        if n == 1:  # 如果数组长度为1,则判断值是否等于target
            return 0 if nums[0] == target else -1 
        
        rotate_index = find_rotate_index(0, n - 1)  # 找到最小值所在的位置
        
        # if target is the smallest element
        if nums[rotate_index] == target:  # 如果最小值的位置等于target
            return rotate_index
        # if array is not rotated, search in the entire array
        if rotate_index == 0:  # 如果最小值的索引是0,则搜索整个数组
            return search(0, n - 1)
        if target < nums[0]:  # 如果target值小于索引为0的值,则遍历较小的数组段
            # search on the right side
            return search(rotate_index, n - 1)
        # search on the left side
        return search(0, rotate_index)  # 如果target大于索引为零的值,则遍历较大的数组段

发布了320 篇原创文章 · 获赞 21 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_37388085/article/details/105311591
今日推荐