迴圈條件lclasssolution
(object):
deffindmin
(self, nums)
: left=
0 right=
len(nums)-1
while leftmid=left+
(right-left)//2
if nums[mid]
>nums[right]
: left=mid+
1else
: right=mid
return nums[left]此題與上一題的區別是,增加了重複元素,所以迴圈條件略有區別,增加了
nums[mid]==nums[r]
等於時的特判,用right-=1跳過重複元素,使得right慢慢向左跳迴圈條件lclass
solution
(object):
deffindmin
(self, nums)
:"""
:type nums: list[int]
:rtype: int
"""left=
0 right=
len(nums)-1
while leftmid=left+
(right-left)//2
if nums[mid]
>nums[right]
: left=mid+
1elif nums[mid]
: right=mid
else
: right-=
1return nums[left]方法1:找到陣列中的最小值後,在第一或第二遞增區域內找目標值
根據上題"153. 尋找旋轉排序陣列中的最小值" 可以得到最小值,若將最小值
minidx
作為旋轉點,則有
class
solution
(object):
defsearch
(self, nums, target)
:"""
:type nums: list[int]
:type target: int
:rtype: int
"""# 找到最小值的下標
deffindmin
(nums)
: l=
0 r=
len(nums)-1
while lmid=l+
(r-l)//2
if nums[mid]
>nums[r]
: l=mid+
1else
: r=mid
return l
# 普通的二分查詢,用於確定目標值下標
defbinarysearch
(nums,target)
: l=
0 r=
len(nums)-1
while l<=r:
mid=l+
(r-l)//2
if nums[mid]
==target:
return mid
elif nums[mid]
>target:
r=mid-
1else
: l=mid+
1return-1
minidx=findmin(nums)
if minidx==0:
#單調遞增,在整個範圍內尋找
return binarysearch(nums,target)
elif target>=nums[0]
:# 在第乙個遞增序列內找
return binarysearch(nums[
0:minidx]
,target)
else
:# target# 如果目標值不在第二遞增序列中,則返回-1,否則返回 minidx+tmp
tmp=binarysearch(nums[minidx:
],target)
return-1
if tmp==-1
else minidx+tmp
方法2:直接二分查詢,在嚴格的遞增序列內找target,其餘情況取反
否則當nums[mid]
class與上題相比,本題增加了重複元素。因此,若檢測到重複元素,則左(右)指標要跳,直到不重複:solution
(object):
defsearch
(self, nums, target)
:"""
:type nums: list[int]
:type target: int
:rtype: int
"""n=
len(nums)
l=0 r=n-
1while l<=r:
mid=l+
(r-l)//2
# 找到後,結束迴圈,跳出
if nums[mid]
==target:
return mid
# 左邊是遞增序列
if nums[mid]
>=nums[l]
:# target 若在遞增序列內,則更新右指標
if nums[l]
<=target: r=mid-
1else
:# 剩餘情況更新左指標
l=mid+
1# 右邊是遞增序列
elif nums[mid]
:# target 若在遞增序列內,則更新左指標
if nums[mid]
: l=mid+
1else
:# 剩餘情況更新右指標
r=mid-
1return-1
# 不滿足條件時,返回-1
如[1,1,1,1,2,1], 可保證跳過相鄰的相同元素與上題相比,增加如下判斷:
if nums[mid]==nums[l]==nums[r]:
l+=1
r-=1
class
solution
(object):
defsearch
(self, nums, target)
:"""
:type nums: list[int]
:type target: int
:rtype: int
"""n=
len(nums)
l=0 r=n-
1while l<=r:
mid=l+
(r-l)//2
# 找到後,結束迴圈,跳出
if nums[mid]
==target:
return
true
# ******與上題相比,增加的部分****** #
""" 如[1,1,1,1,2,1], 可保證跳過相鄰的相同元素
"""if nums[mid]
==nums[l]
==nums[r]
: l+=
1 r-=
1# ******與上題相比,增加的部分****** #
# 左邊是遞增序列
elif nums[mid]
>=nums[l]
:# target 若在遞增序列內,則更新右指標
if nums[l]
<=target: r=mid-
1else
:# 剩餘情況更新左指標
l=mid+
1# 右邊是遞增序列
elif nums[mid]
:# target 若在遞增序列內,則更新左指標
if nums[mid]
: l=mid+
1else
:# 剩餘情況更新右指標
r=mid-
1return
false
# 不滿足條件時,返回-1
搜尋旋轉排序陣列
假設有乙個排序的按未知的旋轉軸旋轉的陣列 比如,0 1 2 4 5 6 7 可能成為4 5 6 7 0 1 2 給定乙個目標值進行搜尋,如果在陣列中找到目標值返回陣列中的索引位置,否則返回 1。你可以假設陣列中不存在重複的元素。分析 特殊的陣列搜尋某一元素問題,二分法。這一題的難點在於如何尋找二分的...
搜尋旋轉排序陣列
假設有乙個排序的按未知的旋轉軸旋轉的陣列 比如,0 1 2 4 5 6 7 可能成為4 5 6 7 0 1 2 給定乙個目標值進行搜尋,如果在陣列中找到目標值返回陣列中的索引位置,否則返回 1。樣例 給出 4,5,1,2,3 和target 1,返回 2 給出 4,5,1,2,3 和target 0...
搜尋旋轉排序陣列
題目 假設按照公升序排序的陣列在預先未知的某個點上進行了旋轉。例如,陣列 0,1,2,4,5,6,7 可能變為 4,5,6,7,0,1,2 搜尋乙個給定的目標值,如果陣列中存在這個目標值,則返回它的索引,否則返回 1 你可以假設陣列中不存在重複的元素。你的演算法時間複雜度必須是 o log n 級別...