搜索旋转排序数组

题目描述:
假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组 [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

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/search-in-rotated-sorted-array

思路要点:
1、二分法找到“断崖点”
2、判断tatget属于左边还是右边,在其中一边使用二分搜索

代码:

import math
from bisect import bisect_left

class Solution:
    def __init__(self,lst,target):
        self.nums=lst
        self.target=target
        self.result=self.search(self.nums,self.target)
    def search(self,nums,target):
        left=0
        right=len(nums)-1
        
        while left<=right:
            mid=math.ceil((left+right)/2)
            if mid==0 or mid==len(nums)-1 or (nums[mid]<nums[mid+1] and nums[mid]<nums[mid-1]) :
                break
            
            if nums[mid]>nums[len(nums)-1]:  #说明断崖点在右边
                left=mid+1
                continue
            if nums[mid]<nums[0]:  #说明断崖点在左边
                right=mid-1
                continue
        steep=mid
        
        if target<nums[0]:
            lst=nums[steep:]
            index=bisect_left(lst, target)
            if index==len(lst):
                return -1
            return index+len(nums)-len(lst)
        else:
            lst=nums[:steep]
            index=bisect_left(lst, target)
            if index==len(lst):
                return -1
            return index
        
            
            
    '''
    left   0  4 4
    right  6  6 4
    mid    3  5 4
    '''
if __name__=='__main__':
    nums=[3,4,5,6,7,0,1,2]
    target=1
    print('数组:\n')
    print(nums)
    print('\n')
    print('target:'+str(target))
     
    solution=Solution(nums,target)
    index=solution.result
    print('index='+str(index))

运行结果:
数组:
[3, 4, 5, 6, 7, 0, 1, 2]
target:1
index=6

数组:
[3, 4, 5, 6, 7, 0, 1, 2]
target:9
index=-1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值