1. 程式人生 > >二分法Python程式碼實現,迭代和非迭代法

二分法Python程式碼實現,迭代和非迭代法

1 看程式碼吧,

#用迭代實現二分法
#寫個類吧
class Solution:
	def binarySearch(self, nums, target):
		return self.search(nums, 0, len(nums) - 1, target)

	def search(self, nums, start, end, target):

		if start > end:
			return -1

		#start, end = 0, len(nums) -1
		mid = (start + end)//2
		if nums[mid] > target:
			return self.search(nums, start, mid, target)
		if nums[mid] == target:
			return mid
		if nums[mid] < target:
			return self.search(nums, mid, end, target)

my_solution = Solution()
nums = [1,2,3,4,5,6]
target = 2
#start, end = 0, len(nums) -1
targetIndex = my_solution.binarySearch(nums, target)
print(targetIndex)
'''
#用迭代實現二分法
#寫個函式吧
def search(nums, start, end, target):

	if start > end:
		return -1

	#start, end = 0, len(nums) -1
	mid = (start + end)//2
	if nums[mid] > target:
		return search(nums, start, mid, target)
	if nums[mid] == target:
		return mid
	if nums[mid] < target:
		return search(nums, mid, end, target)

#my_solution = Solution()
nums = [1,2,3,4,5,6]
target = 2
start, end = 0, len(nums) -1
targetIndex = search(nums, start, end, target)
print(targetIndex)

'''

#二分法,模板實現
class Solution:
    def binarySearch(self, nums, target):
        if len(nums) == 0:
            return -1
        start, end = 0, len(nums) -1
        while (start + 1 < end):
            mid = (start + end) // 2
            if nums[mid] < target:
                start = mid
            else:
                end = mid

                '''
                這裡不能畫蛇添足,要不然錯了,如果碰到nums[mid] == target情況,
                end = mid, nums[end]= nums[mid] == target, 跳轉到最後,return end了
            elif nums[mid] > tartet:
                end = mid
            else:
                return mid 
                '''
                
        if nums[start] == target:
            return start
        if nums[end] == target:
            return end
        return -1

my_solution = Solution()
nums = [1,2,3,4,5,6]
target = 2
targetIndex = my_solution.binarySearch(nums, target)
print(targetIndex)    


為什麼要用 start + 1 < end?而不是 start < end 或者 start <= end?

A: 為了避免死迴圈。二分法的模板中,整個程式架構分為兩個部分:

  1. 通過 while 迴圈,將區間範圍從 n 縮小到 2 (只有 start 和 end 兩個點)。
  2. 在 start 和 end 中判斷是否有解。

start < end 或者 start <= end 在尋找目標最後一次出現的位置的時候,出現死迴圈。

Q: 為什麼明明可以 start = mid + 1 偏偏要寫成 start = mid?

A: 大部分時候,mid 是可以 +1 和 -1 的。在一些特殊情況下,比如尋找目標的最後一次出現的位置時,當 target 與 nums[mid] 相等的時候,是不能夠使用 mid + 1 或者 mid - 1 的。因為會導致漏掉解。那麼為了節省腦力

,統一寫成 start = mid / end = mid 並不會造成任何解的丟失,並且也不會損失效率——log(n) 和 log(n+1) 沒有區別。