topic
Given an n-element sorted (ascending) integer array nums and a target value target, write a function to search for target in nums and return the subscript if the target value exists, and -1 otherwise.
输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4
brute force enumeration
The for loop traverses the elements of the array and judges one by one. Time complexity O(n)
def search(nums, target) -> int:
for i,num in enumerate(nums):
if num == target: return i
return -1
dichotomy
Dichotomy, suitable for such ordered array search.
The idea of dichotomy is to compare the middle value with the target each time, and then narrow the range and then take the middle value...:
- If the middle value < target, shrink left
- If the middle value > target, shrink the right
If the intermediate value = target, it needs to be discussed on a case-by-case basis
- If the array is ordered and non-repeated like [1,2,3,4], it will be found directly
- If the array is in other cases, such as repeated, partially ordered, partially ordered and repeated, the left and right boundaries need to be considered, because there may be multiple numbers equal to the target in the array, and you need to find the leftmost or rightmost number of
Dichotomy time complexity O(logn), n/2^k=1, k=logn
Standard bisection, the array is ordered without repeating elements
[1,2,3,4,5], the array is ordered and has no duplicate elements
while loop implementation
def search(nums, target) -> int:
left,right = 0, len(nums)-1
while left <= right:
mid = (left+right)//2
if nums[mid]==target:
return mid
elif nums[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
recursive implementation
def search(nums,target) -> int:
def searchInternally(nums,target,left,right):
if left<=right:
mid = (left+right)//2
if nums[mid]==target:
return mid
elif nums[mid]<target:
return searchInternally(nums,target,mid+1,right)
else:
return searchInternally(nums,target,left,mid-1)
else:
return -1
return searchInternally(nums,target,0,len(nums)-1)
Consider boundaries
Array has duplicate elements: [1,2,2,2,3]
The array is partially ordered: [4,5,6,1,2,3]
# 查找左边界
def search(nums,target):
left,right = 0, len(nums)-1
while left<right:
mid = (left+right)//2
# 因为有重复元素,并且寻找左边界,所以当匹配到target后,收缩right,继续向左查找
if nums[mid]==target:
right = mid
if nums[mid] > target:
right = mid -1
if nums[mid] < target:
left = mid +1
return left if nums[left]==target else -1
# 查找右边界
def search(nums, target):
left, right = 0, len(nums) - 1
while left < right:
# 因为查找右边界,mid原本的计算是向下取整,导致靠左,所以+1靠右
mid = (left + right) // 2 + 1
if nums[mid] == target:
# 收缩left,继续向右查找
left = mid
if nums[mid] > target:
right = mid - 1
if nums[mid] < target:
left = mid + 1
return right if nums[right] == target else -1
The array is partially ordered and repeated: [1,2,2,3,1,2,2,3]
# 查找左边界
def search(nums, target):
left,right = 0, len(nums)-1
while left < right:
mid = (left+right)//2
if nums[mid]==target:
right = mid
if nums[mid]>target:
# 因为数组部分有序且重复,mid大于target时,
# 有可能mid左侧没有目标值,在右侧有,因此收缩right时只能一点一点收缩
right = right - 1
if nums[mid]<target:
left = mid + 1
return left if nums[left]==target else -1
Dichotomy median overflow
(left+right)//2 Although the intermediate value can be calculated, this simple calculation method may have the possibility of integer overflow.
Although, in python3, int does not overflow.
For example, assuming that the current maximum range of integers is 20, if left=10, right=20, and left+right has exceeded the maximum range, it will overflow.
A more scientific calculation method is: (right-left)//2+left
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。