二分法python上机实验报告_二分查找-Python刷题笔记
二分搜索是一種在有序數組中查找某一特定元素的搜索算法。
二分查找示意圖
搜索過程從數組的中間元素開始,如果中間元素正好是要查找的元素,則搜索過程結束;如果某一特定元素大于或者小于中間元素,則在數組大于或小于中間元素的那一半中查找,而且跟開始一樣從中間元素開始比較。如果在某一步驟數組為空,則代表找不到。這種搜索算法每一次比較都使搜索范圍縮小一半。
查找特定元素
利用遞歸實現
# 返回 x 在 arr 中的索引,如果不存在返回 -1
def binarySearch (arr,l,r, x):
# 基本判斷
if r >= l:
mid = l + (h-l)//2 # 中部
if arr[mid] == x:
return mid
elif arr[mid] > x:
return binarySearch(arr, l, mid-1, x)
else:
return binarySearch(arr, mid+1, r, x)
else:
return False
# 測試
arr = [ 2, 3, 4, 10, 40 ]
x = 10
result = binarySearch(arr,0,len(arr)-1, x)
if result:
print ("元素在數組中的索引為 %d" % result )
else:
print ("元素不在數組中")
循環實現
def binarySearch(arr, target):
low,high = 0,len(arr)-1
while low <= high:
mid = low + (high - low) // 2
if arr[mid] == target:
return mid
elif arr[mid] > target:
high = mid - 1
else:
low = mid + 1
return -1
arr = [ 2, 3, 4, 10, 40 ]
x = 10
result = binarySearch(arr, x)
if result:
print ("元素在數組中的索引為 %d" % result )
else:
print ("元素不在數組中")
把一個數組最開始的若干個元素搬到數組的末尾,我們稱之為數組的旋轉。輸入一個遞增排序的數組的一個旋轉,輸出旋轉數組的最小元素。例如,數組 [3,4,5,1,2] 為 [1,2,3,4,5] 的一個旋轉,該數組的最小值為1。
示例 1:
輸入:[3,4,5,1,2]
輸出:1
class Solution:
def minArray(self, numbers: List[int]) -> int:
l, r = 0, len(numbers)-1
while l <= r:
mid = (l+r)//2
if numbers[mid] > numbers[r]:
l = mid + 1
elif numbers[mid] < numbers[r]:
r = mid
else:
r -= 1
return numbers[l]
image
numbers[mid] > numbers[r]
mid 目前處于左排序數組。也就是說旋轉點在mid右側的區間 [mid+1, r]
numbers[mid] < numbers[r]
mid 目前處于右排序數組 ,即旋轉點一定在mid左側的區間 [l, m]
numbers[mid] = numbers[r]
判斷不了mid位置
[1, 0, 1, 1, 1]:旋轉點 x = 1 ,m=2 在 右排序數組 中。
[1, 1, 1, 0, 1]:旋轉點 x = 3 ,m=2 在 左排序數組 中。
r -= 1 縮小范圍
假設按照升序排序的數組在預先未知的某個點上進行了旋轉。
( 例如,數組 [0,1,2,4,5,6,7] 可能變為 [4,5,6,7,0,1,2] )。
搜索一個給定的目標值,如果數組中存在這個目標值,則返回它的索引,否則返回 -1 。
你可以假設數組中不存在重復的元素。
你的算法時間復雜度必須是 O(log n) 級別。
找到中點值 MID, 它的左側或者右側必有一側為有序數列。
# 假設按照升序排序的數組在預先未知的某個點上進行了旋轉。
# ( 例如,數組 [0,1,2,4,5,6,7] 可能變為 [4,5,6,7,0,1,2] )。
# 搜索一個給定的目標值,如果數組中存在這個目標值,則返回它的索引,否則返回 -1 。
# 你可以假設數組中不存在重復的元素。
# 你的算法時間復雜度必須是 O(log n) 級別。
def search(nums, target):
numslength = len(nums)
l,h = 0, numslength
while l
m = (l+h)//2
if nums[m] == target:
return m
elif nums[m] < target:
if nums[l] == target:
return l
elif nums[l] < nums[m]: # 左側有序,不在左側
l = m + 1
elif nums[l] > nums[m]: # 左側無序,右側有序
if target < nums[l]:
l = m + 1
elif target > nums[l]:
h = m - 1
elif nums[m] > target:
if nums[l] == target:
return l
elif nums[l] < nums[m]: # 左側有序,在左側
if target < nums[l]:
l = m + 1
elif target > nums[l]:
h = m
elif nums[l] > nums[m]: # 左側無序,右側有序
h = m - 1
return -1
x = search([4,5,6,7,0,1,2],3)
print(x)
超時
優化,合并判斷條件
def search(nums, target):
l,h = 0, len(nums)
while l
m = (l+h)//2
if nums[m] == target:
return m
elif nums[l] == target:
return l
elif nums[m] < target:
if target > nums[l] > nums[m]:
h = m
else:
l = m + 1
elif nums[m] > target:
if target < nums[l] < nums[m]:
l = m + 1
else:
h = m
return -1
x = search([4,5,6,7,0,1,2],3)
print(x)
交互式問題
給你一個 山脈數組 mountainArr,請你返回能夠使得 mountainArr.get(index) 等于 target 最小 的下標 index 值。
如果不存在這樣的下標 index,就請返回 -1。
A.length >= 3
0 < i < A.length - 1 條件下
A[0] < A[1] < ... A[i-1] < A[i]
A[i] > A[i+1] > ... > A[A.length - 1]
# """
# This is MountainArray's API interface.
# You should not implement it, or speculate about its implementation
# """
#class MountainArray:
# def get(self, index: int) -> int:
# def length(self) -> int:
class Solution:
def findInMountainArray(self, target: int, mountain_arr: 'MountainArray') -> int:
arr_len = mountain_arr.length()
l,r = 0, arr_len-1
mount_peak_index = 0
# 找峰頂 mount_peak_index
while l < r:
m = (l+r) // 2
ml_val = mountain_arr.get(m-1)
mr_val = mountain_arr.get(m+1)
m_val = mountain_arr.get(m)
if ml_val < m_val and mr_val < m_val:
mount_peak_index = m
break
elif ml_val < m_val < mr_val:
l = m
elif ml_val > m_val > mr_val:
r = m
# 要找等于 target 最小的下標, 先查左側
# 峰頂左側,遞增序列二分查找
l,r = 0,mount_peak_index
while l <= r:
m = (l+r) // 2
m_val = mountain_arr.get(m)
if m_val == target:
return m
elif m_val > target:
r = m-1
elif m_val < target:
l = m+1
# 峰頂右側,遞減序列二分查找
l,r = mount_peak_index,arr_len-1
while l <= r:
m = (l+r) // 2
m_val = mountain_arr.get(m)
if m_val == target:
return m
elif m_val > target:
l = m+1
elif m_val < target:
r = m-1
return -1
Reference
總結
以上是生活随笔為你收集整理的二分法python上机实验报告_二分查找-Python刷题笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C语言中的位域 bit field [转
- 下一篇: python面试技巧和注意事项_Pyth