二分法应用——搜索旋转数组,以前一直在纠结a[0],a[-1],a[mid], target三者关系,其实最简单的还是使用2次二分,先找到旋转数组peak,然后用正常的二分搜索即可!
62 · 搜索旋转排序数组
描述
给定一个有序数组,但是数组以某个元素作为支点进行了旋转(比如,0 1 2 4 5 6 7
可能成为4 5 6 7 0 1 2
)。给定一个目标值target
进行搜索,如果在数组中找到目标值返回数组中的索引位置,否则返回-1
。你可以假设数组中不存在重复的元素。
样例
样例 1:
输入:
数组 = [4, 5, 1, 2, 3]
target = 1
输出:
2
解释:
1在数组中对应索引位置为2。
样例 2:
输入:
数组 = [4, 5, 1, 2, 3]
target = 0
输出:
-1
解释:
0不在数组中,返回-1。
挑战
O(logN) 时间限制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | from typing import ( List , ) class Solution: """ @param a: an integer rotated sorted array @param target: an integer to be searched @return: an integer """ def search( self , a: List [ int ], target: int ) - > int : # write your code here def find_peak(): l, r = 0 , len (a) - 1 while l < r - 1 : mid = (l + r) >> 1 if a[mid] > a[ 0 ]: l = mid else : r = mid if a[l] < a[r]: return r return l def bin_search(l, r): while l < r - 1 : mid = (l + r) >> 1 if a[mid] < target: l = mid else : r = mid if a[l] = = target: return l if a[r] = = target: return r return - 1 if not a: return - 1 if a[ 0 ] < = a[ - 1 ]: return bin_search( 0 , len (a) - 1 ) peak = find_peak() <br> #在前半段搜索 if a[ 0 ] < = target < = a[peak]: return bin_search( 0 , peak) <br> #在后半段搜索 return bin_search(peak + 1 , len (a) - 1 ) |
逻辑非常简单清晰!!!不要再去用以前那种复杂的解法了。。。几个关系给你整蒙逼!!!
比如下面这种,就是用到夹逼的思想:
从两边不断靠近target的值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | class Solution: """ @param A: an integer rotated sorted array @param target: an integer to be searched @return: an integer """ def search( self , A, target): if not A: return - 1 start, end = 0 , len (A) - 1 while start + 1 < end: mid = (start + end) / / 2 if A[mid] > = A[start]: if A[start] < = target < = A[mid]: end = mid else : start = mid else : if A[mid] < = target < = A[end]: start = mid else : end = mid if A[start] = = target: return start if A[end] = = target: return end return - 1 |
1 2 | if A[mid] > = A[start]: if A[start] < = target < = A[mid]: = = 》表示在左半边升序部分<br> <br> else : if A[mid] < = target < = A[end]: = = 》表示在右半边升序部分<br><br>要求逻辑分析非常严谨。。。<br><br><br><br> |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
2020-06-03 AES中的ECB、CTR、MAC、GMAC、GCM
2020-06-03 数字签名算法-RSA、DSA、ECDSA、ECDH
2020-06-03 常用的数字签名算法包括:MD5withRSA/SHA1withRSA/SHA256withRSA/SHA1withDSA/SHA256withDSA/SHA512withDSA/ECDSA等
2018-06-03 leetcode 643. Maximum Average Subarray I
2018-06-03 leetcode 38. Count and Say
2018-06-03 太深了,梯度传不下去,于是有了highway。 干脆连highway的参数都不要,直接变残差,于是有了ResNet。 强行稳定参数的均值和方差,于是有了BatchNorm。RNN梯度不稳定,于是加几个通路和门控,于是有了LSTM。 LSTM简化一下,有了GRU。
2017-06-03 python nltk 入门demo