先判断target在不在数组中,如果在哪一段也就是确定下标区间之后,就用二分查找,这个是最直白的想法,搂了眼题解应该还有更简便的解法,一次循环既可以找到分割点又可以找到目标值
class Solution(object):
def search(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
i = 0
l = len(nums)
if l == 0:
return -1
if l == 1:
if nums[0] != target:
return -1
else: return 0
while i < l - 1 and nums[i + 1] > nums[i]:
i += 1
if nums[0] <= target <= nums[i]:
return self.divide_find(0, i, nums, target)
if i != l - 1:
if nums[i + 1] <= target <= nums[l - 1]:
return self.divide_find(i + 1, l - 1, nums, target)
else:
return -1
else:
return -1
def divide_find(self, l, r, nums, target):
while l <= r:
m = (l + r) / 2
if target == nums[m]:
return m
if target > nums[m]:
l = m + 1
if target < nums[m]:
r = m - 1
return -1
由题解启发而来的解法:
比较中间值与两端点值的大小,如果中间值>右端点,说明至少左端点到中间都是较大的那一段而且是按升序排的;
如果中间值<右端点,说明至少中间到右端点是较小的那一段而且是按升序排的。
还有一个要注意的点是边界值是小于等于还是小于这样的问题
class Solution(object):
def search(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
l = 0
r = len(nums) - 1
while l <= r:
m = (l + r)//2
if nums[m] == target:
return m
if nums[m] < nums[r]:
if nums[m] < target <= nums[r]:
l = m + 1
else:
r = m - 1
else:
if nums[l] <= target < nums[m]:
r = m - 1
else:
l = m + 1
return -1